//****************************************************************************************/ //获取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 "); 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 ", status); return status; } RtlInitUnicodeString(&ustrLinkName, LINK_NAME); if (!NT_SUCCESS(status)) { dprintf("[hello] IoCreateSymbolicLink = 0x%x ", 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 ", 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 "); } NTSTATUS DispatchCreate( PDEVICE_OBJECT pDevObj, PIRP pIrp ) { pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; dprintf("[hello] IRP_MJ_CREATE "); 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 "); 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 "); 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 ", 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 "); 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 "); 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 "); 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 : "); dprintf("%d Questions. ", ntohs(dns->q_count)); dprintf("%d Answers. ", ntohs(dns->ans_count)); dprintf("%d Authoritative Servers. ", ntohs(dns->auth_count)); dprintf("%d Additional records. ", 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)] = '