当前位置:   article > 正文

关于hook ntdll 代码详解

关于hook ntdll 代码详解

UNHOOK ntdll

  1. DWORD unhook() {
  2. //创建该结构体用于获取该dll的信息 将所有成员变量初始化为零
  3. MODULEINFO mi = {};
  4. //获取当前内存的ntdll的句柄
  5. HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
  6. //HANDLE(-1)表示获取当前进程的句柄 该函数用于获取该进程的信息
  7. GetModuleInformation(HANDLE(-1), ntdllModule, &mi, sizeof(mi));
  8. //获取该ntdll的基地址
  9. LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;
  10. //调用CreateFileA打开新的一个ntdll
  11. HANDLE ntdllFile = CreateFileA("c:\\windows\\system32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  12. //将该新的ntdll映射到内存中 但是还没有映射到当前进程中
  13. HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
  14. //MapViewOfFile将文件映射的视图映射到调用进程的地址空间中 也就是当前的进程
  15. LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);
  16. //获取该ntdll的PE结构的DOS头 (旧的)
  17. PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
  18. PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);
  19. for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {
  20. //每个节的头是固定大小且是连续的。一个节头挨着一个节头的比如rdata的节头完了之后就是紧挨着data节头的。IMAGE_SIZEOF_SECTION_HEADER确实是40字节
  21. PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
  22. //获取节的头之后判断name是不是等于text,因为要覆盖的是text的内容 hookedSectionHeader->Name获取的是字节不是char 因此要转为char strcmp要求是char *
  23. if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) {
  24. DWORD oldProtection = 0;
  25. //VirtualProtect修改旧的 ntdll的保护属性为可读可写可执行(PAGE_EXECUTE_READWRITE),并且将原来的保护属性保存在oldProtection中 以下仅仅支持.text节的
  26. bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
  27. //两个dll由于第一个节是空的在内存中,而text节又是第二个节,因此VirtualAddress是一样的 这样就将旧ntdll中test节的内容覆盖成了新的
  28. memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);
  29. //还原保护属性
  30. isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
  31. }
  32. }
  33. CloseHandle(ntdllFile);
  34. CloseHandle(ntdllMapping);
  35. FreeLibrary(ntdllModule);
  36. return 0;
  37. }

关于代码中的IMAGE_SIZEOF_SECTION_HEADER

节的头是连续的 每个节的头的大小 即IMAGE_SIZEOF_SECTION_HEADER都等于40

找一个dll看看 确实节的头是连续 也确实大小是 5*8=40字节

节头存放的是节的各种信息包括 节的名称、虚拟地址、大小等但是 不是存放的具体内容

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/323232
推荐阅读
相关标签
  

闽ICP备14008679号