DNS解析
//****************************************************************************************/ //获取DNS #include "DNS.h" //全局变量 PDNSADDRANDURL global_pwsadata; NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString ) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ustrLinkName; UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj; int s_dns = 0; unsigned char hostname[100] = { "www.debugman.com" }; //if (DBG) { // __asm int 3 } dprintf("[hello] DriverEntry\n"); pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; pDriverObj->DriverUnload = DriverUnload; RtlInitUnicodeString(&ustrDevName, DEVICE_NAME); status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj); if (!NT_SUCCESS(status)) { dprintf("[hello] IoCreateDevice = 0x%x\n", status); return status; } RtlInitUnicodeString(&ustrLinkName, LINK_NAME); if (!NT_SUCCESS(status)) { dprintf("[hello] IoCreateSymbolicLink = 0x%x\n", status); IoDeleteDevice(pDevObj); return status; } global_pwsadata = (PDNSADDRANDURL)ExAllocatePool(0, sizeof(DNSADDRANDURL)); s_dns = ReadDnsServerFromRegistry(); //返回网络字节顺序 global_pwsadata->serveur_dns = s_dns; gethostbyname(hostname); dprintf(" remote ip address is %x\n", global_pwsadata->urladdr); return STATUS_SUCCESS; } VOID DriverUnload( PDRIVER_OBJECT pDriverObj ) { UNICODE_STRING strLink; RtlInitUnicodeString(&strLink, LINK_NAME); // // 添加卸载代码 // IoDeleteSymbolicLink(&strLink); IoDeleteDevice(pDriverObj->DeviceObject); dprintf("[hello] Unloaded\n"); } NTSTATUS DispatchCreate( PDEVICE_OBJECT pDevObj, PIRP pIrp ) { pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; dprintf("[hello] IRP_MJ_CREATE\n"); IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DispatchClose( PDEVICE_OBJECT pDevObj, PIRP pIrp ) { pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; dprintf("[hello] IRP_MJ_CLOSE\n"); IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DispatchIoctl( PDEVICE_OBJECT pDevObj, PIRP pIrp ) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; PIO_STACK_LOCATION pIrpStack; ULONG uIoControlCode; PVOID pIoBuffer; ULONG uInSize; ULONG uOutSize; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (uIoControlCode) { case IOCTL_HELLO: { dprintf("[hello] Hello\n"); status = STATUS_SUCCESS; } break; } if (status == STATUS_SUCCESS) pIrp->IoStatus.Information = uOutSize; else pIrp->IoStatus.Information = 0; ///////////////////////////////////// pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; } /* 返回网络字节顺序 */ int ReadDnsServerFromRegistry() { //Variables locales NTSTATUS status = STATUS_UNSUCCESSFUL; WCHAR ChaineRegistre[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; UNICODE_STRING usRegistryKey = { 0 }; OBJECT_ATTRIBUTES obNomClefRegistre = { 0 }; HANDLE RegHandle = 0; UNICODE_STRING usRegistryKeySub = { 0 }; OBJECT_ATTRIBUTES obNomClefRegistreSub = { 0 }; HANDLE RegHandleSub = 0; WCHAR ChaineEnableDHCP[] = L"EnableDHCP"; WCHAR ChaineNameServer[] = L"NameServer"; WCHAR ChaineDhcpNameServer[] = L"DhcpNameServer"; //有问题这个,注册表里好像没有 Win10下DhcpServer //DhcpServer char informations_lues[256]; ULONG size_lue = 0; KEY_VALUE_FULL_INFORMATION *KeyValue = NULL; char adresses_ips_dns[40]; int compteur_subkey = 0; unsigned int adresse = 0; ANSI_STRING AnsiString; UNICODE_STRING CurrentName; RtlInitUnicodeString(&usRegistryKey, ChaineRegistre); InitializeObjectAttributes(&obNomClefRegistre, &usRegistryKey, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenKey(&RegHandle, KEY_READ, &obNomClefRegistre); //打开 L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces" if (status != STATUS_SUCCESS) { return -1; } compteur_subkey = 0; status = STATUS_SUCCESS; while (TRUE) { memset(informations_lues, 0, 256); status = ZwEnumerateKey(RegHandle, compteur_subkey, KeyBasicInformation, &informations_lues, 256, &size_lue); if (status != STATUS_SUCCESS) break; RtlInitUnicodeString(&usRegistryKeySub, ((*(KEY_BASIC_INFORMATION*)&informations_lues).Name)); InitializeObjectAttributes(&obNomClefRegistreSub, &usRegistryKeySub, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); obNomClefRegistreSub.RootDirectory = RegHandle; status = ZwOpenKey(&RegHandleSub, KEY_READ, &obNomClefRegistreSub); if (status != STATUS_SUCCESS) { compteur_subkey++; continue; } memset(informations_lues, 0, 256); RtlInitUnicodeString(&usRegistryKey, ChaineEnableDHCP); status = ZwQueryValueKey(RegHandleSub, &usRegistryKey, KeyValueFullInformation, &informations_lues, 256, &size_lue); if (status != STATUS_SUCCESS) { compteur_subkey++; ZwClose(RegHandleSub); continue; } KeyValue = (KEY_VALUE_FULL_INFORMATION *)informations_lues; if (*(int*)(informations_lues + KeyValue->DataOffset)) { RtlInitUnicodeString(&usRegistryKey, ChaineDhcpNameServer); } else { RtlInitUnicodeString(&usRegistryKey, ChaineNameServer); } memset(informations_lues, 0, 256); status = ZwQueryValueKey(RegHandleSub, &usRegistryKey, KeyValueFullInformation, &informations_lues, 256, &size_lue); if (status != STATUS_SUCCESS) { compteur_subkey++; ZwClose(RegHandleSub); continue; } RtlZeroMemory(adresses_ips_dns, 40); RtlInitUnicodeString(&CurrentName, informations_lues + KeyValue->DataOffset); RtlUnicodeStringToAnsiString(&AnsiString, &CurrentName, TRUE); RtlCopyMemory(adresses_ips_dns, AnsiString.Buffer, 40); dprintf("DNS SERVICE IP %s\n", adresses_ips_dns); ZwClose(RegHandleSub); adresse = inet_addr(adresses_ips_dns); if (adresse == 0) { compteur_subkey++; continue; } ZwClose(RegHandle); return adresse; compteur_subkey++; } ZwClose(RegHandle); return -1; } //获取了DNS的ip后问题就容易处理,剩下构造dns请求包和udp的相关东西~~ //因为dns请求的协议要求获得本机地址,要去取本机地址,代码如下 /* 返回网络字节顺序 */ int ReadHostIPsFromRegistry() { NTSTATUS status = STATUS_UNSUCCESSFUL; int* pHostentArray = NULL; char* pHostentData = NULL; WCHAR ChaineRegistre[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; UNICODE_STRING usRegistryKey = { 0 }; OBJECT_ATTRIBUTES obNomClefRegistre = { 0 }; HANDLE RegHandle = 0; UNICODE_STRING usRegistryKeySub = { 0 }; OBJECT_ATTRIBUTES obNomClefRegistreSub = { 0 }; HANDLE RegHandleSub = 0; WCHAR ChaineEnableDHCP[] = L"EnableDHCP"; WCHAR ChaineIPAddress[] = L"IPAddress"; WCHAR ChaineDhcpIPAddress[] = L"DhcpIPAddress"; char informations_lues[256]; ULONG size_lue = 0; KEY_VALUE_FULL_INFORMATION *KeyValue = NULL; char adresse_ip[20]; int compteur_subkey = 0; unsigned int adresse = 0; ANSI_STRING AnsiString; UNICODE_STRING CurrentName; RtlInitUnicodeString(&usRegistryKey, ChaineRegistre); InitializeObjectAttributes(&obNomClefRegistre, &usRegistryKey, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenKey(&RegHandle,//打开主键 KEY_READ, &obNomClefRegistre); if (status != STATUS_SUCCESS) { return -1; } compteur_subkey = 0;//子键的个数 status = STATUS_SUCCESS; while (TRUE) { memset(informations_lues, 0, 256); status = ZwEnumerateKey(RegHandle, compteur_subkey, KeyBasicInformation, &informations_lues, 256, &size_lue); if (status != STATUS_SUCCESS) break; RtlInitUnicodeString(&usRegistryKeySub, ((*(KEY_BASIC_INFORMATION*)&informations_lues).Name)); DbgPrint("subkey is %ws", usRegistryKeySub.Buffer); InitializeObjectAttributes(&obNomClefRegistreSub, &usRegistryKeySub, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); obNomClefRegistreSub.RootDirectory = RegHandle; status = ZwOpenKey(&RegHandleSub, KEY_READ, &obNomClefRegistreSub); if (status != STATUS_SUCCESS) { compteur_subkey++; dprintf("[niveau socket] !! ReadHostIPsFromRegistry : Echec d'ouverture du registre sur sous-clef\n"); continue; } memset(informations_lues, 0, 256); RtlInitUnicodeString(&usRegistryKey, ChaineEnableDHCP); status = ZwQueryValueKey(RegHandleSub, &usRegistryKey, KeyValueFullInformation, &informations_lues, 256, &size_lue); if (status != STATUS_SUCCESS) { compteur_subkey++; dprintf("[niveau socket] !! ReadHostIPsFromRegistry : Echec lecture valeur EnableDHCP\n"); ZwClose(RegHandleSub); continue; } KeyValue = (KEY_VALUE_FULL_INFORMATION *)informations_lues; if (*(int*)(informations_lues + KeyValue->DataOffset)) { RtlInitUnicodeString(&usRegistryKey, ChaineDhcpIPAddress); } else { RtlInitUnicodeString(&usRegistryKey, ChaineIPAddress); } memset(informations_lues, 0, 256); status = ZwQueryValueKey(RegHandleSub, &usRegistryKey, KeyValueFullInformation, &informations_lues, 256, &size_lue); if (status != STATUS_SUCCESS) { compteur_subkey++; ZwClose(RegHandleSub); continue; } RtlZeroMemory(adresse_ip, 20); RtlInitUnicodeString(&CurrentName, informations_lues + KeyValue->DataOffset); RtlUnicodeStringToAnsiString(&AnsiString, &CurrentName, TRUE); RtlCopyMemory(adresse_ip, AnsiString.Buffer, 20); dprintf("HOST IP %s", adresse_ip); ZwClose(RegHandleSub); adresse = inet_addr(adresse_ip); if (adresse == 0) { compteur_subkey++; continue; } else { return adresse; } } ZwClose(RegHandle); return adresse; } //下面开始贴具体DNS请求过程的代码了 //已经获取得到网络字节顺序 PHOSTENT gethostbyname(IN char *name) { struct sockaddr_in sockaddr_dns = { 0 }; unsigned char* phostent_buf = NULL; if (global_pwsadata->serveur_dns == 0) { return NULL; } phostent_buf = ExAllocatePoolWithTag(0, 2048, 'doki'); if (phostent_buf == NULL) { return NULL; } RtlZeroMemory(phostent_buf, 2048); sockaddr_dns.sin_family = AF_INET; sockaddr_dns.sin_addr.s_addr = global_pwsadata->serveur_dns;//DNS的主机地址 sockaddr_dns.sin_port = HTONS(53);//dns 服务器固定端口 if (query_dns(sockaddr_dns, name, phostent_buf, FALSE) != -1) { return (PHOSTENT)phostent_buf; } else { ExFreePool(phostent_buf); return NULL; } } int query_dns(IN struct sockaddr_in sockaddr_dns, IN char* URL, //www.DebugMan.com OUT char *hostent_buf,//返回的值 IN int rdns)//rdns 是否反向查询 { struct sockaddr_in sockaddr_bind = { 0 }; //干什么用的? int com_socket = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; int size_string_requete_format_dns = 0; int size_string_requete = 0; unsigned char * buf = NULL;//需要构造的缓冲区 unsigned char * reader; //读取的位置指针 DNS_HEADER * dns = NULL; int size_buffer_dns = 0;// sendto must be know length of databuf char * res_record_crawler = NULL; CUSTOM_RES_RECORD * res_record = NULL; unsigned int * adresse_ip = NULL; int compteur_reponses = 0; PHOSTENT hostent = NULL; char* hostent_content = NULL; char** hostent_array = NULL;//指向指针的指针 unsigned char * qname = NULL; QUESTION * qinfo = NULL; int lock = 0, i, j, k; int stop, lenthqname; struct sockaddr_in a;//便于记录读取的IP struct RES_RECORD answers[20], auth[20], addit[20]; //the replies from the DNS server PUCHAR returnaddr;//指针 int lenth = sizeof(DNS_HEADER); buf = ExAllocatePoolWithTag(0, 2048, 'doki'); if (buf == NULL) { return NULL; } RtlZeroMemory(buf, 2048); /* +---------------------+ | Header | +---------------------+ | Question | the question for the name server +---------------------+ | Answer | RRs answering the question +---------------------+ | Authority | RRs pointing toward an authority +---------------------+ | Additional | RRs holding additional information +---------------------+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ */ //1 Construction du message DNS //buffer : DNS_HEADER | nom modifi?| QUESTION dns = (DNS_HEADER*)buf; dns->id = 1234; //Flags DNS dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = HTONS(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname = (unsigned char*)&buf[sizeof(DNS_HEADER)]; //www.google.com ==>> 3www6google3com ChangetoDnsNameFormat(qname, URL); qinfo = (struct QUESTION*)&buf[sizeof(DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it qinfo->qtype = HTONS(1); //we are requesting the ipv4 address qinfo->qclass = HTONS(1); //its internet always is 1 size_buffer_dns = sizeof(DNS_HEADER) + strlen(qname) + 1 + sizeof(QUESTION);//33 //com_socket = socket(AF_INET, SOCK_DGRAM ,IPPROTO_UDP); //udp 数据报查询 com_socket = socket(2, 2, 17); if (com_socket == -1) { ExFreePool(buf); return -1; } status = sendto(com_socket, buf, size_buffer_dns, 0, &sockaddr_dns, sizeof(sockaddr_dns)); if (status == -1) { ExFreePool(buf); status = close(com_socket); if (status == -1) { ; } return -1; } k = sizeof(sockaddr_dns); status = recvfrom(com_socket, buf, 1024 * 2, 0, &sockaddr_dns, &k); if (status == -1) { ExFreePool(buf); status = close(com_socket); if (status == -1) { ; } return -1; } dprintf("received ok \n "); status = close(com_socket); if (status == -1) { return -1; } dns = (struct DNS_HEADER*)buf; if (dns->ans_count == 0) { ExFreePool(buf); return -1; } else { //http://www.codeproject.com/KB/IP/dns_query.aspx 如果你还不知道返回数据格式,可以参考这篇文章 //move ahead of the dns header and the query field //从返回的数据开始读取,也就是去除自己的构造部分 reader = &buf[sizeof(DNS_HEADER) + (strlen((const char*)qname) + 1) + sizeof(QUESTION)]; dprintf("The response contains : \n"); dprintf("%d Questions.\n", ntohs(dns->q_count)); dprintf("%d Answers.\n", ntohs(dns->ans_count)); dprintf("%d Authoritative Servers.\n", ntohs(dns->auth_count)); dprintf("%d Additional records.\n", ntohs(dns->add_count)); //reading answers stop = 0; for (i = 0;i<ntohs(dns->ans_count);i++) { answers[i].name = ReadName(reader, buf, &stop); reader = reader + stop; answers[i].resource = (struct R_DATA*)(reader); reader = reader + sizeof(struct R_DATA); if (ntohs(answers[i].resource->type) == 1) //if its an ipv4 address { answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len)); for (j = 0; j<ntohs(answers[i].resource->data_len); j++) answers[i].rdata[j] = reader[j]; answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0'; reader = reader + ntohs(answers[i].resource->data_len); } else { answers[i].rdata = ReadName(reader, buf, &stop); reader = reader + stop; } } //read authorities for (i = 0;i<ntohs(dns->auth_count);i++) { auth[i].name = ReadName(reader, buf, &stop); reader += stop; auth[i].resource = (struct R_DATA*)(reader); reader += sizeof(struct R_DATA); auth[i].rdata = ReadName(reader, buf, &stop); reader += stop; } //read additional for (i = 0;i<ntohs(dns->add_count);i++) { addit[i].name = ReadName(reader, buf, &stop); reader += stop; addit[i].resource = (struct R_DATA*)(reader); reader += sizeof(struct R_DATA); if (ntohs(addit[i].resource->type) == 1) { addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len)); for (j = 0;j<ntohs(addit[i].resource->data_len);j++) addit[i].rdata[j] = reader[j]; addit[i].rdata[ntohs(addit[i].resource->data_len)] = '\0'; reader += ntohs(addit[i].resource->data_len); } else { addit[i].rdata = ReadName(reader, buf, &stop); reader += stop; } } //print answers for (i = 0;i<ntohs(dns->ans_count);i++) { //printf("\nAnswer : %d",i+1); dprintf("Name : %s ", answers[i].name); if (ntohs(answers[i].resource->type) == 1) //IPv4 address { long *p; p = (long*)answers[i].rdata; a.sin_addr.s_addr = (*p); //working without ntohl dprintf("has IPv4 address : %x\n", *p); RtlCopyMemory(&(global_pwsadata->urladdr), p, 4); //保存在全局变量中 returnaddr = ExAllocatePoolWithTag(0, 16, 'doki'); if (returnaddr == NULL) { return NULL; } RtlZeroMemory(returnaddr, 16); RtlCopyMemory(returnaddr, inet_ntoa(a.sin_addr), 16); dprintf("has IPv4 address : %s\n", returnaddr[i]); ExFreePool(returnaddr); } if (ntohs(answers[i].resource->type) == 5) //Canonical name for an alias dprintf("has alias name : %s\n", answers[i].rdata); dprintf("\n"); } //print authorities for (i = 0;i<ntohs(dns->auth_count);i++) { //printf("\nAuthorities : %d",i+1); dprintf("Name : %s ", auth[i].name); if (ntohs(auth[i].resource->type) == 2) dprintf("has authoritative nameserver : %s", auth[i].rdata); dprintf("\n"); } //print additional resource records for (i = 0;i<ntohs(dns->add_count);i++) { //printf("\nAdditional : %d",i+1); dprintf("Name : %s ", addit[i].name); if (ntohs(addit[i].resource->type) == 1) { long *p; p = (long*)addit[i].rdata; a.sin_addr.s_addr = (*p); //working without ntohl dprintf("has IPv4 address : %s", inet_ntoa(a.sin_addr)); } dprintf("\n"); } } ExFreePool(buf); return 0; } unsigned char* ReadName(unsigned char* reader, unsigned char* buffer, int* count) { unsigned char *name; unsigned int p = 0, jumped = 0, offset; int i, j; *count = 1; name = (unsigned char*)malloc(256); name[0] = '\0'; //read the names in 3www6google3com format while (*reader != 0) { if (*reader >= 192) { offset = (*reader) * 256 + *(reader + 1) - 49152; //49152 = 11000000 00000000 ;) reader = buffer + offset - 1; jumped = 1; //we have jumped to another location so counting wont go up! } else name[p++] = *reader; reader = reader + 1; if (jumped == 0) *count = *count + 1; //if we havent jumped to another location then we can count up } name[p] = '\0'; //string complete if (jumped == 1) *count = *count + 1; //number of steps we actually moved forward in the packet ChangefromDnsNameFormat(name); return name; } PVOID malloc(int size) { return ExAllocatePoolWithTag(0, size, 'doki');//分配内部缓冲区 } //this will convert www.google.com to 3www6google3com ;got it :) void ChangetoDnsNameFormat(unsigned char* dns, unsigned char* host) { int lock = 0, i; strcat((char*)host, "."); for (i = 0;i<(int)strlen((char*)host);i++) { if (host[i] == '.') { *dns++ = i - lock; for (;lock<i;lock++) { *dns++ = host[lock]; } lock++; //or lock=i+1; } } *dns++ = '\0'; } //this will convert 3www6google3com to www.google.com ;got it :) void ChangefromDnsNameFormat(unsigned char* name) { int i, j; char p; //now convert 3www6google3com0 to www.google.com for (i = 0;i<(int)strlen((const char*)name);i++) { p = name[i]; for (j = 0;j<(int)p;j++) { name[i] = name[i + 1]; i = i + 1; } name[i] = '.'; } name[i - 1] = '\0'; //remove the last dot } int __cdecl bind(int socket, const struct sockaddr *addr, int addrlen) { PSOCKET s = (PSOCKET)-socket; const struct sockaddr_in* localAddr = (const struct sockaddr_in*) addr; UNICODE_STRING devName; NTSTATUS status; if (s->isBound || addr == NULL || addrlen < sizeof(struct sockaddr_in)) { return -1; } if (s->type == SOCK_DGRAM) { RtlInitUnicodeString(&devName, L"\\Device\\Udp"); } else if (s->type == SOCK_STREAM) { RtlInitUnicodeString(&devName, L"\\Device\\Tcp"); } else { return -1; } status = tdi_open_transport_address( &devName, localAddr->sin_addr.s_addr, localAddr->sin_port, s->isShared, &s->addressHandle, &s->addressFileObject ); if (!NT_SUCCESS(status)) { s->addressFileObject = NULL; s->addressHandle = (HANDLE)-1; return status; } if (s->type == SOCK_STREAM) { tdi_set_event_handler(s->addressFileObject, TDI_EVENT_DISCONNECT, event_disconnect, s); } s->isBound = TRUE; return 0; } NTSTATUS event_disconnect(PVOID TdiEventContext, CONNECTION_CONTEXT ConnectionContext, LONG DisconnectDataLength, PVOID DisconnectData, LONG DisconnectInformationLength, PVOID DisconnectInformation, ULONG DisconnectFlags) { PSOCKET s = (PSOCKET)TdiEventContext; PSTREAM_SOCKET streamSocket = (PSTREAM_SOCKET)ConnectionContext; KeSetEvent(&streamSocket->disconnectEvent, 0, FALSE); return STATUS_SUCCESS; } NTSTATUS tdi_set_event_handler(PFILE_OBJECT addressFileObject, LONG eventType, PVOID eventHandler, PVOID eventContext) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(addressFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, devObj, addressFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildSetEventHandler(irp, devObj, addressFileObject, NULL, NULL, eventType, eventHandler, eventContext); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return status; } int __cdecl close(int socket) { PSOCKET s = (PSOCKET)-socket; if (s->isBound) { if (s->type == SOCK_STREAM && s->streamSocket) { if (s->isConnected) { if (!s->isShuttingdown) { tdi_disconnect(s->streamSocket->connectionFileObject, TDI_DISCONNECT_RELEASE); } KeWaitForSingleObject(&s->streamSocket->disconnectEvent, Executive, KernelMode, FALSE, NULL); } if (s->streamSocket->connectionFileObject) { tdi_disassociate_address(s->streamSocket->connectionFileObject); ObDereferenceObject(s->streamSocket->connectionFileObject); } if (s->streamSocket->connectionHandle != (HANDLE)-1) { ZwClose(s->streamSocket->connectionHandle); } ExFreePool(s->streamSocket); } if (s->type == SOCK_DGRAM || s->type == SOCK_STREAM) { ObDereferenceObject(s->addressFileObject); if (s->addressHandle != (HANDLE)-1) { ZwClose(s->addressHandle); } } } ExFreePool(s); return 0; } NTSTATUS tdi_disconnect(PFILE_OBJECT connectionFileObject, ULONG flags) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildDisconnect(irp, devObj, connectionFileObject, NULL, NULL, NULL, flags, NULL, NULL); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return status; } NTSTATUS tdi_disassociate_address(PFILE_OBJECT connectionFileObject) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_DISASSOCIATE_ADDRESS, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildDisassociateAddress(irp, devObj, connectionFileObject, NULL, NULL); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return status; } NTSTATUS tdi_open_transport_address(PUNICODE_STRING devName, ULONG addr, USHORT port, int shared, PHANDLE addressHandle, PFILE_OBJECT *addressFileObject) { OBJECT_ATTRIBUTES attr; PFILE_FULL_EA_INFORMATION eaBuffer; ULONG eaSize; PTA_IP_ADDRESS localAddr; IO_STATUS_BLOCK iosb; NTSTATUS status; #if (VER_PRODUCTBUILD >= 2195) InitializeObjectAttributes(&attr, devName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); #else InitializeObjectAttributes(&attr, devName, OBJ_CASE_INSENSITIVE, NULL, NULL); #endif eaSize = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) + TDI_TRANSPORT_ADDRESS_LENGTH + 1 + sizeof(TA_IP_ADDRESS); eaBuffer = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(PagedPool, eaSize); if (eaBuffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; eaBuffer->EaValueLength = sizeof(TA_IP_ADDRESS); RtlCopyMemory(eaBuffer->EaName, TdiTransportAddress, eaBuffer->EaNameLength + 1); localAddr = (PTA_IP_ADDRESS)(eaBuffer->EaName + eaBuffer->EaNameLength + 1); localAddr->TAAddressCount = 1; localAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; localAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; localAddr->Address[0].Address[0].sin_port = port; localAddr->Address[0].Address[0].in_addr = addr; RtlZeroMemory(localAddr->Address[0].Address[0].sin_zero, sizeof(localAddr->Address[0].Address[0].sin_zero)); status = ZwCreateFile( addressHandle, GENERIC_READ | GENERIC_WRITE, &attr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, shared ? FILE_SHARE_READ | FILE_SHARE_WRITE : 0, FILE_OPEN, 0, eaBuffer, eaSize ); ExFreePool(eaBuffer); if (!NT_SUCCESS(status)) { return status; } status = ObReferenceObjectByHandle(*addressHandle, FILE_ALL_ACCESS, NULL, KernelMode, addressFileObject, NULL); if (!NT_SUCCESS(status)) { ZwClose(*addressHandle); return status; } return STATUS_SUCCESS; } NTSTATUS tdi_send_dgram(PFILE_OBJECT addressFileObject, ULONG addr, USHORT port, const char *buf, int len) { PDEVICE_OBJECT devObj; KEVENT event; PTDI_CONNECTION_INFORMATION remoteInfo; PTA_IP_ADDRESS remoteAddr; PIRP irp; PMDL mdl; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(addressFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); remoteInfo = (PTDI_CONNECTION_INFORMATION)ExAllocatePool(NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); if (remoteInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(remoteInfo, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); remoteInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); remoteInfo->RemoteAddress = (PUCHAR)remoteInfo + sizeof(TDI_CONNECTION_INFORMATION); remoteAddr = (PTA_IP_ADDRESS)remoteInfo->RemoteAddress; remoteAddr->TAAddressCount = 1; remoteAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; remoteAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; remoteAddr->Address[0].Address[0].sin_port = port; remoteAddr->Address[0].Address[0].in_addr = addr; irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, devObj, addressFileObject, &event, &iosb); if (irp == NULL) { ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } if (len) { mdl = IoAllocateMdl((void*)buf, len, FALSE, FALSE, NULL); if (mdl == NULL) { IoFreeIrp(irp); ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages(mdl, KernelMode, IoReadAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); ExFreePool(remoteInfo); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildSendDatagram(irp, devObj, addressFileObject, NULL, NULL, len ? mdl : 0, len, remoteInfo); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } ExFreePool(remoteInfo); return NT_SUCCESS(status) ? iosb.Information : status; } int __cdecl sendto(int socket, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen) { { PSOCKET s = (PSOCKET)-socket; const struct sockaddr_in* remoteAddr = (const struct sockaddr_in*) addr; struct sockaddr_in localAddr; NTSTATUS status; /* if (s->type == SOCK_STREAM) { return send(socket, buf, len, flags); } */ // else if (s->type == SOCK_DGRAM) { if (addr == NULL || addrlen < sizeof(struct sockaddr_in)) { return -1; } if (!s->isBound) { struct sockaddr_in localAddr; NTSTATUS status; //定义在前面 localAddr.sin_family = AF_INET;//2 localAddr.sin_port = 0; localAddr.sin_addr.s_addr = ReadHostIPsFromRegistry(); status = bind(socket, (struct sockaddr*) &localAddr, sizeof(localAddr)); if (!NT_SUCCESS(status)) { return status; } } return tdi_send_dgram( s->addressFileObject, remoteAddr->sin_addr.s_addr, remoteAddr->sin_port, buf, len); } else { return -1; } } } char * inet_ntoa(IN struct in_addr in) { PUCHAR p; UCHAR buffer[20]; PUCHAR b; // // A number of applications apparently depend on calling inet_ntoa() // without first calling WSAStartup(). Because of this, we must perform // our own explicit thread initialization check here. // b = buffer; // // In an unrolled loop, calculate the string value for each of the four // bytes in an IP address. Note that for values less than 100 we will // do one or two extra assignments, but we save a test/jump with this // algorithm. // p = (PUCHAR)∈ *b = NToACharStrings[*p][0]; *(b + 1) = NToACharStrings[*p][1]; *(b + 2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b++ = '.'; p++; *b = NToACharStrings[*p][0]; *(b + 1) = NToACharStrings[*p][1]; *(b + 2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b++ = '.'; p++; *b = NToACharStrings[*p][0]; *(b + 1) = NToACharStrings[*p][1]; *(b + 2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b++ = '.'; p++; *b = NToACharStrings[*p][0]; *(b + 1) = NToACharStrings[*p][1]; *(b + 2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b = '\0'; dprintf("buffer %s \n", buffer);//注意打印buffer return(buffer); } /* * Internet address interpretation routine. * All the network library routines call this * routine to interpret entries in the data bases * which are expected to be an address. * The value returned is in network order. */ unsigned long inet_addr( IN const char *cp ) { register unsigned long val, base, n; register char c; unsigned long parts[4], *pp = parts; // WS_ENTER( "inet_addr", (PVOID)cp, NULL, NULL, NULL ); again: /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, other=decimal. */ val = 0; base = 10; if (*cp == '0') { base = 8, cp++; if (*cp == 'x' || *cp == 'X') base = 16, cp++; } while (c = *cp) { if (isdigit(c)) { val = (val * base) + (c - '0'); cp++; continue; } if (base == 16 && isxdigit(c)) { val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); cp++; continue; } break; } if (*cp == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16-bits) * a.b (with b treated as 24 bits) */ /* GSS - next line was corrected on 8/5/89, was 'parts + 4' */ if (pp >= parts + 3) { //WS_EXIT( "inet_addr", -1, TRUE ); return ((unsigned long)-1); } *pp++ = val, cp++; goto again; } /* * Check for trailing characters. */ if (*cp && !isspace(*cp)) { // WS_EXIT( "inet_addr", -1, TRUE ); return (INADDR_NONE); } *pp++ = val; /* * Concoct the address according to * the number of parts specified. */ n = (unsigned long)(pp - parts); switch ((int)n) { case 1: /* a -- 32 bits */ val = parts[0]; break; case 2: /* a.b -- 8.24 bits */ if ((parts[0] > 0xff) || (parts[1] > 0xffffff)) { //WS_EXIT( "inet_addr", -1, TRUE ); return(INADDR_NONE); } val = (parts[0] << 24) | (parts[1] & 0xffffff); break; case 3: /* a.b.c -- 8.8.16 bits */ if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xffff)) { //WS_EXIT( "inet_addr", -1, TRUE ); return(INADDR_NONE); } val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) | (parts[2] & 0xffff); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff) || (parts[3] > 0xff)) { // WS_EXIT( "inet_addr", -1, TRUE ); return(INADDR_NONE); } val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) | ((parts[2] & 0xff) << 8) | (parts[3] & 0xff); break; default: //WS_EXIT( "inet_addr", -1, TRUE ); return (INADDR_NONE); } val = htonl(val); // WS_EXIT( "inet_addr", val, FALSE ); return (val); } //com_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//udp 数据报查询 int __cdecl socket(int af, int type, int protocol) { PSOCKET s; if (af != AF_INET || (type != SOCK_DGRAM && type != SOCK_STREAM) || (type == SOCK_DGRAM && protocol != IPPROTO_UDP && protocol != 0) || (type == SOCK_STREAM && protocol != IPPROTO_TCP && protocol != 0) ) { return STATUS_INVALID_PARAMETER; } s = (PSOCKET)ExAllocatePool(NonPagedPool, sizeof(SOCKET)); if (!s) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(s, sizeof(SOCKET)); s->type = type; s->addressHandle = (HANDLE)-1; //自己添加一行 s->isBound = FALSE; return -(int)s; } int __cdecl recvfrom(int socket, char *buf, int len, int flags, struct sockaddr *addr, int *addrlen) { PSOCKET s = (PSOCKET)-socket; struct sockaddr_in* returnAddr = (struct sockaddr_in*) addr; /* if (s->type == SOCK_STREAM) { return recv(socket, buf, len, flags); } */ // else if (s->type == SOCK_DGRAM) { u_long* sin_addr = 0; u_short* sin_port = 0; if (!s->isBound) { return -1; } if (addr != NULL && addrlen != NULL && *addrlen >= sizeof(struct sockaddr_in)) { sin_addr = &returnAddr->sin_addr.s_addr; sin_port = &returnAddr->sin_port; *addrlen = sizeof(struct sockaddr_in); } return tdi_recv_dgram( s->addressFileObject, sin_addr, sin_port, buf, len, TDI_RECEIVE_NORMAL ); } else { return -1; } } NTSTATUS tdi_recv_dgram(PFILE_OBJECT addressFileObject, PULONG addr, PUSHORT port, char *buf, int len, ULONG flags) { PDEVICE_OBJECT devObj; KEVENT event; PTDI_CONNECTION_INFORMATION remoteInfo; PTDI_CONNECTION_INFORMATION returnInfo; PTA_IP_ADDRESS returnAddr; PIRP irp; PMDL mdl; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(addressFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); remoteInfo = (PTDI_CONNECTION_INFORMATION)ExAllocatePool(NonPagedPool, 2 * sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); if (remoteInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(remoteInfo, 2 * sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); remoteInfo->RemoteAddressLength = 0; remoteInfo->RemoteAddress = NULL; returnInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)remoteInfo + sizeof(TDI_CONNECTION_INFORMATION)); returnInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); returnInfo->RemoteAddress = (PUCHAR)returnInfo + sizeof(TDI_CONNECTION_INFORMATION); returnAddr = (PTA_IP_ADDRESS)returnInfo->RemoteAddress; returnAddr->TAAddressCount = 1; returnAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; returnAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, devObj, addressFileObject, &event, &iosb); if (irp == NULL) { ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } if (len) { mdl = IoAllocateMdl((void*)buf, len, FALSE, FALSE, NULL); if (mdl == NULL) { IoFreeIrp(irp); ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); ExFreePool(remoteInfo); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildReceiveDatagram(irp, devObj, addressFileObject, NULL, NULL, len ? mdl : 0, len, remoteInfo, returnInfo, flags); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } if (addr) { *addr = returnAddr->Address[0].Address[0].in_addr; } if (port) { *port = returnAddr->Address[0].Address[0].sin_port; } ExFreePool(remoteInfo); return NT_SUCCESS(status) ? iosb.Information : status; } /////////////////////////////// END OF FILE /////////////////////////////// #pragma once #ifndef _HELLO_H #define _HELLO_H 1 #include <ntifs.h> #include <ntddk.h> #include <tdikrnl.h> //#define PF_INET TDI_ADDRESS_TYPE_IP #define AF_INET 2 #define SOCK_STREAM 1 //TCP #define SOCK_DGRAM 2 //UDP #define SOCK_RAW 3 //RAW 是winsock.h中定义的 #define IPPROTO_ICMP 1 #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 #define TDI_MAX_SOCKET 256 #define TDI_MAX_BACKLOG 20 #define TDI_TCP_DEVICE_NAME_W L"\\Device\\Tcp" #define TDI_UDP_DEVICE_NAME_W L"\\Device\\Udp" #define TDI_RAW_DEVICE_NAME_W L"\\Device\\RawIp" #define TDI_TIMEOUT_CONNECT_SEC 60 #define TDI_TIMEOUT_DISCONNECT_SEC 60 #define TDI_TIMEOUT_COMMUNICATION 60 #define SOCKET_STATUS_CLEAR 0 #define SOCKET_STATUS_ALLOCATED 1 #define SOCKET_STATUS_TRANSPORT 2 #define SOCKET_STATUS_CONNECTION 3 #define SOCKET_STATUS_CON_AND_TRANS 4 #define SOCKET_STATUS_ASSOCIATED 5 #define SOCKET_STATUS_LISTEN 6 #define SOCKET_STATUS_WAITING_INBOUND 7 #define SOCKET_STATUS_DISCONNECTED 8 #define SOCKET_STATUS_CONNECTED 9 #define SOCKET_STATUS_CHANGING 10 #define WSA_NOT_ENOUGH_MEMORY 8 #define WSAEMFILE 10024 #define WSAEPROTOTYPE 10041 #define WSAEPROTONOSUPPORT 10043 #define WSAESHUTDOWN 10058 #define WSANO_DATA 11004 unsigned char NToACharStrings[][4] = { '0', 'x', 'x', 1, '1', 'x', 'x', 1, '2', 'x', 'x', 1, '3', 'x', 'x', 1, '4', 'x', 'x', 1, '5', 'x', 'x', 1, '6', 'x', 'x', 1, '7', 'x', 'x', 1, '8', 'x', 'x', 1, '9', 'x', 'x', 1, '1', '0', 'x', 2, '1', '1', 'x', 2, '1', '2', 'x', 2, '1', '3', 'x', 2, '1', '4', 'x', 2, '1', '5', 'x', 2, '1', '6', 'x', 2, '1', '7', 'x', 2, '1', '8', 'x', 2, '1', '9', 'x', 2, '2', '0', 'x', 2, '2', '1', 'x', 2, '2', '2', 'x', 2, '2', '3', 'x', 2, '2', '4', 'x', 2, '2', '5', 'x', 2, '2', '6', 'x', 2, '2', '7', 'x', 2, '2', '8', 'x', 2, '2', '9', 'x', 2, '3', '0', 'x', 2, '3', '1', 'x', 2, '3', '2', 'x', 2, '3', '3', 'x', 2, '3', '4', 'x', 2, '3', '5', 'x', 2, '3', '6', 'x', 2, '3', '7', 'x', 2, '3', '8', 'x', 2, '3', '9', 'x', 2, '4', '0', 'x', 2, '4', '1', 'x', 2, '4', '2', 'x', 2, '4', '3', 'x', 2, '4', '4', 'x', 2, '4', '5', 'x', 2, '4', '6', 'x', 2, '4', '7', 'x', 2, '4', '8', 'x', 2, '4', '9', 'x', 2, '5', '0', 'x', 2, '5', '1', 'x', 2, '5', '2', 'x', 2, '5', '3', 'x', 2, '5', '4', 'x', 2, '5', '5', 'x', 2, '5', '6', 'x', 2, '5', '7', 'x', 2, '5', '8', 'x', 2, '5', '9', 'x', 2, '6', '0', 'x', 2, '6', '1', 'x', 2, '6', '2', 'x', 2, '6', '3', 'x', 2, '6', '4', 'x', 2, '6', '5', 'x', 2, '6', '6', 'x', 2, '6', '7', 'x', 2, '6', '8', 'x', 2, '6', '9', 'x', 2, '7', '0', 'x', 2, '7', '1', 'x', 2, '7', '2', 'x', 2, '7', '3', 'x', 2, '7', '4', 'x', 2, '7', '5', 'x', 2, '7', '6', 'x', 2, '7', '7', 'x', 2, '7', '8', 'x', 2, '7', '9', 'x', 2, '8', '0', 'x', 2, '8', '1', 'x', 2, '8', '2', 'x', 2, '8', '3', 'x', 2, '8', '4', 'x', 2, '8', '5', 'x', 2, '8', '6', 'x', 2, '8', '7', 'x', 2, '8', '8', 'x', 2, '8', '9', 'x', 2, '9', '0', 'x', 2, '9', '1', 'x', 2, '9', '2', 'x', 2, '9', '3', 'x', 2, '9', '4', 'x', 2, '9', '5', 'x', 2, '9', '6', 'x', 2, '9', '7', 'x', 2, '9', '8', 'x', 2, '9', '9', 'x', 2, '1', '0', '0', 3, '1', '0', '1', 3, '1', '0', '2', 3, '1', '0', '3', 3, '1', '0', '4', 3, '1', '0', '5', 3, '1', '0', '6', 3, '1', '0', '7', 3, '1', '0', '8', 3, '1', '0', '9', 3, '1', '1', '0', 3, '1', '1', '1', 3, '1', '1', '2', 3, '1', '1', '3', 3, '1', '1', '4', 3, '1', '1', '5', 3, '1', '1', '6', 3, '1', '1', '7', 3, '1', '1', '8', 3, '1', '1', '9', 3, '1', '2', '0', 3, '1', '2', '1', 3, '1', '2', '2', 3, '1', '2', '3', 3, '1', '2', '4', 3, '1', '2', '5', 3, '1', '2', '6', 3, '1', '2', '7', 3, '1', '2', '8', 3, '1', '2', '9', 3, '1', '3', '0', 3, '1', '3', '1', 3, '1', '3', '2', 3, '1', '3', '3', 3, '1', '3', '4', 3, '1', '3', '5', 3, '1', '3', '6', 3, '1', '3', '7', 3, '1', '3', '8', 3, '1', '3', '9', 3, '1', '4', '0', 3, '1', '4', '1', 3, '1', '4', '2', 3, '1', '4', '3', 3, '1', '4', '4', 3, '1', '4', '5', 3, '1', '4', '6', 3, '1', '4', '7', 3, '1', '4', '8', 3, '1', '4', '9', 3, '1', '5', '0', 3, '1', '5', '1', 3, '1', '5', '2', 3, '1', '5', '3', 3, '1', '5', '4', 3, '1', '5', '5', 3, '1', '5', '6', 3, '1', '5', '7', 3, '1', '5', '8', 3, '1', '5', '9', 3, '1', '6', '0', 3, '1', '6', '1', 3, '1', '6', '2', 3, '1', '6', '3', 3, '1', '6', '4', 3, '1', '6', '5', 3, '1', '6', '6', 3, '1', '6', '7', 3, '1', '6', '8', 3, '1', '6', '9', 3, '1', '7', '0', 3, '1', '7', '1', 3, '1', '7', '2', 3, '1', '7', '3', 3, '1', '7', '4', 3, '1', '7', '5', 3, '1', '7', '6', 3, '1', '7', '7', 3, '1', '7', '8', 3, '1', '7', '9', 3, '1', '8', '0', 3, '1', '8', '1', 3, '1', '8', '2', 3, '1', '8', '3', 3, '1', '8', '4', 3, '1', '8', '5', 3, '1', '8', '6', 3, '1', '8', '7', 3, '1', '8', '8', 3, '1', '8', '9', 3, '1', '9', '0', 3, '1', '9', '1', 3, '1', '9', '2', 3, '1', '9', '3', 3, '1', '9', '4', 3, '1', '9', '5', 3, '1', '9', '6', 3, '1', '9', '7', 3, '1', '9', '8', 3, '1', '9', '9', 3, '2', '0', '0', 3, '2', '0', '1', 3, '2', '0', '2', 3, '2', '0', '3', 3, '2', '0', '4', 3, '2', '0', '5', 3, '2', '0', '6', 3, '2', '0', '7', 3, '2', '0', '8', 3, '2', '0', '9', 3, '2', '1', '0', 3, '2', '1', '1', 3, '2', '1', '2', 3, '2', '1', '3', 3, '2', '1', '4', 3, '2', '1', '5', 3, '2', '1', '6', 3, '2', '1', '7', 3, '2', '1', '8', 3, '2', '1', '9', 3, '2', '2', '0', 3, '2', '2', '1', 3, '2', '2', '2', 3, '2', '2', '3', 3, '2', '2', '4', 3, '2', '2', '5', 3, '2', '2', '6', 3, '2', '2', '7', 3, '2', '2', '8', 3, '2', '2', '9', 3, '2', '3', '0', 3, '2', '3', '1', 3, '2', '3', '2', 3, '2', '3', '3', 3, '2', '3', '4', 3, '2', '3', '5', 3, '2', '3', '6', 3, '2', '3', '7', 3, '2', '3', '8', 3, '2', '3', '9', 3, '2', '4', '0', 3, '2', '4', '1', 3, '2', '4', '2', 3, '2', '4', '3', 3, '2', '4', '4', 3, '2', '4', '5', 3, '2', '4', '6', 3, '2', '4', '7', 3, '2', '4', '8', 3, '2', '4', '9', 3, '2', '5', '0', 3, '2', '5', '1', 3, '2', '5', '2', 3, '2', '5', '3', 3, '2', '5', '4', 3, '2', '5', '5', 3 }; typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; struct in_addr { union { struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b; struct { u_short s_w1, s_w2; } S_un_w; u_long S_addr; } S_un; }; #define s_addr S_un.S_addr struct sockaddr_in { short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; }sockaddr; #define h_addr h_addr_list[0] //Constant sized fields of the resource record structure #pragma pack(push, 1) struct R_DATA { unsigned short type; unsigned short _class; unsigned int ttl; unsigned short data_len; }; #pragma pack(pop) //Pointers to resource record contents struct RES_RECORD { unsigned char *name; struct R_DATA *resource; unsigned char *rdata; }; typedef struct { char * h_name; char ** h_aliases; short h_addrtype; short h_length; unsigned int ** h_addr_list; } HOSTENT, *PHOSTENT; //定义一样的 typedef struct _DNSADDRANDURL { int serveur_dns;// int urladdr;//已解析的 } DNSADDRANDURL, *PDNSADDRANDURL; typedef struct { unsigned short id; // identification number unsigned char rd : 1; // recursion desired unsigned char tc : 1; // truncated message unsigned char aa : 1; // authoritive answer unsigned char opcode : 4; // purpose of message unsigned char qr : 1; // query/response flag unsigned char rcode : 4; // response code unsigned char cd : 1; // checking disabled unsigned char ad : 1; // authenticated data unsigned char z : 1; // its z! reserved unsigned char ra : 1; // recursion available unsigned short q_count; // number of question entries unsigned short ans_count; // number of answer entries unsigned short auth_count; // number of authority entries unsigned short add_count; // number of resource entries } DNS_HEADER; //DNS Question typedef struct { unsigned short qtype; unsigned short qclass; } QUESTION; typedef struct { unsigned short name; unsigned short type; unsigned short _class; unsigned short ttl_hi; unsigned short ttl_low; unsigned short data_len; unsigned char rdata[1]; }CUSTOM_RES_RECORD; typedef struct _STREAM_SOCKET { HANDLE connectionHandle; PFILE_OBJECT connectionFileObject; KEVENT disconnectEvent; } STREAM_SOCKET, *PSTREAM_SOCKET; typedef struct _SOCKET { int type; BOOLEAN isBound; BOOLEAN isConnected; BOOLEAN isListening; BOOLEAN isShuttingdown; BOOLEAN isShared; HANDLE addressHandle; PFILE_OBJECT addressFileObject; PSTREAM_SOCKET streamSocket; struct sockaddr_in peer; } SOCKET, *PSOCKET; #define INADDR_NONE 0xffffffff #define htonl(l) \ ( ( ((l) >> 24) & 0x000000FFL ) | \ ( ((l) >> 8) & 0x0000FF00L ) | \ ( ((l) << 8) & 0x00FF0000L ) | \ ( ((l) << 24) & 0xFF000000L ) ) #define ntohs(s) \ ( ( ((s) >> 8) & 0x00FF ) | \ ( ((s) << 8) & 0xFF00 ) ) #define HTONS(a) (((0xFF&a)<<8) + ((0xFF00&a)>>8)) #define NTOHS(s) ((((s)>> 8) & 0x00FF)|(((s)<<8)&0xFF00)) //找了好久哦,其实也很简单 #define dprintf if (DBG) DbgPrint #define nprintf DbgPrint #define DEVICE_NAME L"\\Device\\devhello" // Driver Name #define LINK_NAME L"\\DosDevices\\hello" // Link Name // // The device driver IOCTLs // #define IOCTL_BASE 0x800 #define MY_CTL_CODE(i) \ CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_HELLO MY_CTL_CODE(0) ///////////////////////////////////////////////////////////////////// NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString); NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp); NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp); VOID DriverUnload(PDRIVER_OBJECT pDriverObj); NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp); ///////////////////////////////////////////////////////////////////// //函数声明 char* inet_ntoa(struct in_addr in); unsigned long inet_addr(const char *cp); PVOID malloc(int size); int ReadDnsServerFromRegistry(); int ReadHostIPsFromRegistry(); PHOSTENT gethostbyname(char *name); int query_dns(struct sockaddr_in sockaddr_dns, char* nom_a_resoudre, char *hostent_buf, int rdns); int build_dns_query(char* URL, int* taille_buffer_dns, int rdns); void ChangetoDnsNameFormat(unsigned char* dns, unsigned char* host); void ChangefromDnsNameFormat(unsigned char* name); int __cdecl bind(int socket, const struct sockaddr *addr, int addrlen); NTSTATUS tdi_open_transport_address(PUNICODE_STRING devName, ULONG addr, USHORT port, int shared, PHANDLE addressHandle, PFILE_OBJECT *addressFileObject); NTSTATUS tdi_set_event_handler(PFILE_OBJECT addressFileObject, LONG eventType, PVOID eventHandler, PVOID eventContext); int __cdecl sendto(int socket, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen); int __cdecl send(int socket, const char *buf, int len, int flags); NTSTATUS tdi_send_dgram(PFILE_OBJECT addressFileObject, ULONG addr, USHORT port, const char *buf, int len); int __cdecl socket(int af, int type, int protocol); NTSTATUS tdi_disconnect(PFILE_OBJECT connectionFileObject, ULONG flags); NTSTATUS tdi_disassociate_address(PFILE_OBJECT connectionFileObject); int __cdecl close(int socket); int __cdecl recvfrom(int socket, char *buf, int len, int flags, struct sockaddr *addr, int *addrlen); unsigned char* ReadName(unsigned char* reader, unsigned char* buffer, int* count); NTSTATUS tdi_recv_dgram(PFILE_OBJECT addressFileObject, PULONG addr, PUSHORT port, char *buf, int len, ULONG flags); NTSTATUS event_disconnect(PVOID TdiEventContext, CONNECTION_CONTEXT ConnectionContext, LONG DisconnectDataLength, PVOID DisconnectData, LONG DisconnectInformationLength, PVOID DisconnectInformation, ULONG DisconnectFlags); int __cdecl recv(int socket, char *buf, int len, int flags); NTSTATUS tdi_recv_stream(PFILE_OBJECT connectionFileObject, char *buf, int len, ULONG flags); int __cdecl socket(int af, int type, int protocol); NTSTATUS tdi_set_event_handler(PFILE_OBJECT addressFileObject, LONG eventType, PVOID eventHandler, PVOID eventContext); NTSTATUS tdi_send_dgram(PFILE_OBJECT addressFileObject, ULONG addr, USHORT port, const char *buf, int len); NTSTATUS tdi_send_stream(PFILE_OBJECT connectionFileObject, const char *buf, int len, ULONG flags); NTSTATUS tdi_open_transport_address(PUNICODE_STRING devName, ULONG addr, USHORT port, int shared, PHANDLE addressHandle, PFILE_OBJECT *addressFileObject); #endif /////////////////////////////// END OF FILE ///////////////////////////////
爱程序 不爱bug
爱生活 不爱黑眼圈
我和你们一样 我和你们不一样
我不是凡客 我要做geek