VOID DbgPrintContext(PCONTEXT pContext, BOOL bDisas) { #if _WIN64 DbgMsg("[+] rax= " HEX_FORMAT " rbx= " HEX_FORMAT " rcx= " HEX_FORMAT "\n", pContext->Rax, pContext->Rbx, pContext->Rcx); DbgMsg("[+] rdx= " HEX_FORMAT " rsi= " HEX_FORMAT " rdi= " HEX_FORMAT "\n", pContext->Rdx, pContext->Rsi, pContext->Rdi); DbgMsg("[+] rip= " HEX_FORMAT " rsp= " HEX_FORMAT " rbp= " HEX_FORMAT "\n", pContext->Rip, pContext->Rsp, pContext->Rbp); DbgMsg("[+] r8= " HEX_FORMAT " r9= " HEX_FORMAT " r10= " HEX_FORMAT "\n", pContext->R8, pContext->R9, pContext->R10); DbgMsg("[+] r11= " HEX_FORMAT " r12= " HEX_FORMAT " r13= " HEX_FORMAT "\n", pContext->R11, pContext->R12, pContext->R13); DbgMsg("[+] r14= " HEX_FORMAT " r15= " HEX_FORMAT "\n", pContext->R14, pContext->R15); #else DbgMsg("[+] eax= " HEX_FORMAT " ebx= " HEX_FORMAT " ecx= " HEX_FORMAT " edx= " HEX_FORMAT " esi= " HEX_FORMAT " edi= " HEX_FORMAT "\n", pContext->Eax, pContext->Ebx, pContext->Ecx, pContext->Edx, pContext->Esi, pContext->Edi); DbgMsg("[+] eip= " HEX_FORMAT " esp= " HEX_FORMAT " ebp= " HEX_FORMAT "\n", pContext->Eip, pContext->Esp, pContext->Ebp); #endif DbgMsg("[+] dr0= " HEX_FORMAT " dr1= " HEX_FORMAT " dr2= " HEX_FORMAT "\n", pContext->Dr0, pContext->Dr1, pContext->Dr2); DbgMsg("[+] dr3= " HEX_FORMAT " dr6= " HEX_FORMAT " dr7= " HEX_FORMAT "\n", pContext->Dr3, pContext->Dr6, pContext->Dr7); if (bDisas == TRUE) { #if _WIN64 DisasOne((PBYTE)pContext->Rip, pContext->Rip, NULL); #else DisasOne((PBYTE)pContext->Eip, pContext->Eip, NULL); #endif DbgMsg("---\n"); } }
BOOL SearchAutoIAT(ULONG_PTR BaseAddress, ULONG_PTR SearchStart, DWORD SearchSize) { PBYTE pActual; ULONG_PTR Addr; ULONG_PTR DestAddr; ULONG_PTR IATStart; ULONG_PTR IATEnd; for (pActual = (PBYTE)SearchStart; pActual < (PBYTE)(SearchStart + SearchSize - 1); pActual++) { #ifdef _WIN64 if ((pActual[0] == 0xFF) && ((pActual[1] == 0x25) || (pActual[1] == 0x15) || (pActual[1] == 0x35))) { /* call qword ptr[rip+delta] jmp qword ptr[rip+delta] push qword ptr[rip+delta] */ Addr = *(PDWORD)(pActual + 2) + (ULONG_PTR)pActual + 6; #else if ((pActual[0] == 0xFF) && ((pActual[1] == 0x25) || (pActual[1] == 0x15))) { Addr = *(PDWORD)(pActual + 2); #endif if ((!IsBadReadMemory((PVOID)Addr, sizeof (ULONG_PTR))) && (!IsBadReadMemory((PVOID)*(PULONG_PTR)Addr, sizeof (ULONG_PTR)))) { DestAddr = *(PULONG_PTR)Addr; if (IsAnExport(DestAddr) == TRUE) { DisasOne(pActual, (ULONG_PTR)pActual, NULL); IATStart = SearchIATStart(BaseAddress, Addr); DbgMsg("[+] IATStart : "HEX_FORMAT"\n", IATStart); IATEnd = SearchIATEnd(BaseAddress, Addr); DbgMsg("[+] IATEnd : "HEX_FORMAT"\n", IATEnd); DbgMsg("[+] windbg : dps "HEX_FORMAT" L((("HEX_FORMAT" - "HEX_FORMAT") / %d) + 1)\n", IATStart, IATEnd, IATStart, sizeof (ULONG_PTR)); pinfo.Importer.StartIATRVA = (IATStart - BaseAddress); BuildNewImport(IATStart, IATEnd); //DebugBreak(); break; } } } } return TRUE; } ULONG_PTR SearchIATStart(ULONG_PTR BaseAddress, ULONG_PTR SearchStart) { DWORD VirtualAddr; ULONG_PTR SectionStart; DWORD dwBlankSpace = 0; VirtualAddr = (DWORD)GetSectionInfo(BaseAddress, SearchStart - BaseAddress, SEC_VIRT_ADDR); if (VirtualAddr == 0) { DbgMsg("[-] SearchIATStart - GetSectionInfo failed\n"); return 0; } SectionStart = VirtualAddr + BaseAddress; while (SearchStart > SectionStart) { if (dwBlankSpace == 2) break; SearchStart = SearchStart - SIZE_IMPORT_ENTRY; if (!IsBadReadMemory((PVOID)SearchStart, SIZE_IMPORT_ENTRY)) { if (IsBadReadMemory(*(PVOID*)SearchStart, SIZE_IMPORT_ENTRY)) { dwBlankSpace += 1; continue; } dwBlankSpace = 0; } else { break; } } if (SearchStart == SectionStart) return SearchStart; return SearchStart + (SIZE_IMPORT_ENTRY * 2); }
/* ==== 32 ==== 8B 0D XX XX XX XX mov ecx, [address] 8B 15 XX XX XX XX mov edx, [address] 8B 1D XX XX XX XX mov ebx, [address] 8B 25 XX XX XX XX mov esp, [address] 8B 2D XX XX XX XX mov ebp, [address] 8B 35 XX XX XX XX mov esi, [address] 8B 3D XX XX XX XX mov edi, [address] A1 XX XX XX XX mov eax, [address] ==== 64 ==== 48 8B 0D XX XX XX XX mov rcx, [rip + delta] 48 8B 15 XX XX XX XX mov rdx, [rip + delta] 48 8B 1D XX XX XX XX mov rbx, [rip + delta] 48 8B 25 XX XX XX XX mov rsp, [rip + delta] 48 8B 2D XX XX XX XX mov rbp, [rip + delta] 48 8B 35 XX XX XX XX mov rsi, [rip + delta] 48 8B 3D XX XX XX XX mov rdi, [rip + delta] 48 8B 05 XX XX XX XX mov rax, [rip + delta] */ VOID LookIndirectCallImport(PBYTE pActual) { ULONG_PTR Addr; ULONG_PTR DestAddr; #ifdef _WIN64 if ((pActual[0] == 0x48) && (pActual[1] == 0x8B) && ((pActual[2] == 0x0D) || (pActual[2] == 0x15) || (pActual[2] == 0x1D) || (pActual[2] == 0x25) || (pActual[2] == 0x2D) || (pActual[2] == 0x35) || (pActual[2] == 0x3D) || (pActual[2] == 0x05))) { Addr = *(PDWORD)(pActual + 3) + (ULONG_PTR)pActual + 7; #else if ((pActual[0] == 0xA1) || ((pActual[0] == 0x8B) && ((pActual[2] == 0x0D) || (pActual[2] == 0x15) || (pActual[2] == 0x1D) || (pActual[2] == 0x25) || (pActual[2] == 0x2D) || (pActual[2] == 0x35) || (pActual[2] == 0x3D)))) { Addr = *(PDWORD)(pActual + 2); #endif if ((!IsBadReadMemory((PVOID)Addr, sizeof (ULONG_PTR))) && (!IsBadReadMemory((PVOID)*(PULONG_PTR)Addr, sizeof (ULONG_PTR)))) { DestAddr = *(PULONG_PTR)Addr; if (IsAnExport(DestAddr) == TRUE) { DisasOne(pActual, (ULONG_PTR)pActual); } } } } /* ==== 32 ==== FF 15 XX XX XX XX call [address] FF 25 XX XX XX XX jmp [address] FF 35 XX XX XX XX push [address] ==== 64 ==== FF 15 XX XX XX XX call [rip + delta] FF 25 XX XX XX XX jmp [rip + delta] FF 35 XX XX XX XX push [rip + delta] */ VOID LookDirectCallImport(PBYTE pActual) { ULONG_PTR Addr; ULONG_PTR DestAddr; if ((pActual[0] == 0xFF) && ((pActual[1] == 0x25) || (pActual[1] == 0x15) || (pActual[1] == 0x35))) { #ifdef _WIN64 Addr = *(PDWORD)(pActual + 2) + (ULONG_PTR)pActual + 6; #else Addr = *(PDWORD)(pActual + 2); #endif if ((!IsBadReadMemory((PVOID)Addr, sizeof (ULONG_PTR))) && (!IsBadReadMemory((PVOID)*(PULONG_PTR)Addr, sizeof (ULONG_PTR)))) { DestAddr = *(PULONG_PTR)Addr; if (IsAnExport(DestAddr) == TRUE) { DisasOne(pActual, (ULONG_PTR)pActual); } } } }