|
VC如何读取谋个内存地址处的eax值
动态方法、正解 |
|
[原创][求助]脱一个壳的问题
刚刚弄了一下,原来是该病毒有采取anti-dump技术,通过绕过Anti-Dump顺利脱壳,现在分享下我脱壳的过程: 首先用PEID查看该EXE,如下图所示,虽然无法查出是具体哪种壳,但是从它的节名可以推出应该是UPX 接着打开OD加载该EXE,开始的时候,使用快捷键ATL+M打开内存窗口,在该EXE的第一个节处按下F2设置内存断点,如下图所示: 按下SHIFT+F9运行,断点停留在地址00A90747处,仔细一查看,这部分主要是循环解压内存的每个字节数据,bl每次存储的就是被解压的数据 00A90743 /76 0B jbe short 00A90750 00A90745 |8A1A mov bl, byte ptr [edx] [COLOR="Red"]00A90747 |8818 mov byte ptr [eax], bl[/COLOR] 00A90749 |40 inc eax 00A9074A |42 inc edx 00A9074B |49 dec ecx 00A9074C |85C9 test ecx, ecx 00A9074E ^|77 F5 ja short 00A90745 完成解压后,继续单步执行,直到返回CALL函数的空间,如下所示,仔细对比前后的代码,可以知道这是循环解压各个节数据 00A904DB 8B45 C0 mov eax, dword ptr [ebp-40] 00A904DE 8B50 0C mov edx, dword ptr [eax+C] 00A904E1 0355 DC add edx, dword ptr [ebp-24] 00A904E4 8B48 14 mov ecx, dword ptr [eax+14] 00A904E7 03CE add ecx, esi 00A904E9 894D B4 mov dword ptr [ebp-4C], ecx 00A904EC 8B40 10 mov eax, dword ptr [eax+10] 00A904EF 50 push eax 00A904F0 8B45 B4 mov eax, dword ptr [ebp-4C] 00A904F3 50 push eax 00A904F4 52 push edx [COLOR="red"]00A904F5 FF53 57 call dword ptr [ebx+57][/COLOR] 00A904F8 8345 C0 28 add dword ptr [ebp-40], 28 00A904FC 4F dec edi 00A904FD 85FF test edi, edi 00A904FF ^ 77 DA ja short 00A904DB 继续单步运行,到了如下代码:两个CALL函数,分别是LoadLibraryA和GetProcAddress,这里主要是完成IAT的填充 0051426D . 037E 04 add edi, dword ptr [esi+4] 00514270 ? 83C6 0C add esi, 0C 00514273 . 57 push edi [COLOR="red"]00514274 ? FF95 65FAFFFF call dword ptr [ebp-59B][/COLOR] 0051427A ? 5F pop edi 0051427B . 5A pop edx 0051427C ? 5B pop ebx 0051427D . 83F8 00 cmp eax, 0 00514280 ? 74 59 je short 005142DB 00514282 ? 8985 D1F9FFFF mov dword ptr [ebp-62F], eax 00514288 ? 033E add edi, dword ptr [esi] 0051428A ? 83C6 04 add esi, 4 0051428D . 33C9 xor ecx, ecx 0051428F . 8A0E mov cl, byte ptr [esi] 00514291 . 83F9 00 cmp ecx, 0 00514294 ? 75 03 jnz short 00514299 00514296 ? 46 inc esi 00514297 .^ EB B3 jmp short 0051424C 00514299 . 8BC7 mov eax, edi 0051429B . 03F9 add edi, ecx 0051429D . 52 push edx 0051429E ? 53 push ebx 0051429F . 50 push eax 005142A0 ? 8038 FF cmp byte ptr [eax], 0FF 005142A3 . 75 08 jnz short 005142AD 005142A5 . 40 inc eax 005142A6 ? 8B00 mov eax, dword ptr [eax] 005142A8 ? 25 FFFFFF7F and eax, 7FFFFFFF 005142AD . 8A0F mov cl, byte ptr [edi] 005142AF . C607 00 mov byte ptr [edi], 0 005142B2 ? 51 push ecx 005142B3 . 50 push eax 005142B4 ? FFB5 D1F9FFFF push dword ptr [ebp-62F] [COLOR="red"]005142BA ? FF95 69FAFFFF call dword ptr [ebp-597][/COLOR] 005142C0 ? 59 pop ecx 005142C1 . 5A pop edx 005142C2 ? 5B pop ebx 005142C3 . 5A pop edx 005142C4 ? 83F8 00 cmp eax, 0 005142C7 . 74 12 je short 005142DB 005142C9 . 880F mov byte ptr [edi], cl 005142CB . 8946 FC mov dword ptr [esi-4], eax 005142CE ? FF76 FC push dword ptr [esi-4] 005142D1 . 8F03 pop dword ptr [ebx] 005142D3 . 83C3 04 add ebx, 4 005142D6 ? 46 inc esi 005142D7 .^ EB B4 jmp short 0051428D 然后继续单步运行: 遇到一条跳转指令JMP 404B54,跟踪过去后,可以推断出这里就是OEP了 接着用LoadPE在该EXE的进程的右键菜单先点击执行“correct ImageSize"(这里就是为什么之前我脱不了壳的原因,anti-dump),然后在dump full 最后重建输入表,使用ImportREC工具很简单方便,如下图所示,填写正确的OEP,和IAT表的RVA和SIZE后点击“Get Imports”,很幸运,都是正确的函数信息,那么最后直接Fix Dump到刚才DUMP下来的文件 至此,该病毒的脱壳成功!!! |
|
[原创]自己写的PE分析工具(附源代码)
分析NOTEPAD.EXE结果如下 ——————————Dos Header Info—————————— dos RVA : 0x00000000 dos size : 0x000000e0 ——————————sections Info—————————— section name : .text VirtualAddress : 0x00001000 VirtualSize : 0x00008000 RawAddress : 0x00000400 RwaSize : 0x00007800 section name : .data VirtualAddress : 0x00009000 VirtualSize : 0x00002000 RawAddress : 0x00007c00 RwaSize : 0x00000800 section name : .rsrc VirtualAddress : 0x0000b000 VirtualSize : 0x00008000 RawAddress : 0x00008400 RwaSize : 0x00008000 ——————————Header Info—————————— imageBase : 0x01000000 entryPoint : 0x0000739d sectionAlignment : 0x00001000 fileAlignment : 0x00000200 numSections : 0x00000003 ——————————Import Table—————————— comdlg32.dll 0x0000000f PageSetupDlgW comdlg32.dll 0x00000006 FindTextW comdlg32.dll 0x00000012 PrintDlgExW comdlg32.dll 0x00000003 ChooseFontW comdlg32.dll 0x00000008 GetFileTitleW comdlg32.dll 0x0000000a GetOpenFileNameW comdlg32.dll 0x00000015 ReplaceTextW comdlg32.dll 0x00000004 CommDlgExtendedError comdlg32.dll 0x0000000c GetSaveFileNameW SHELL32.dll 0x0000001f DragFinish SHELL32.dll 0x00000023 DragQueryFileW SHELL32.dll 0x0000001e DragAcceptFiles SHELL32.dll 0x00000103 ShellAboutW WINSPOOL.DRV 0x00000078 GetPrinterDriverW WINSPOOL.DRV 0x0000001b ClosePrinter WINSPOOL.DRV 0x0000007e OpenPrinterW COMCTL32.dll 0x00000008 CreateStatusWindowW msvcrt.dll 0x0000004e _XcptFilter msvcrt.dll 0x000000f6 _exit msvcrt.dll 0x000000c5 _c_exit msvcrt.dll 0x00000317 time msvcrt.dll 0x000002d4 localtime msvcrt.dll 0x000000c8 _cexit msvcrt.dll 0x000002c6 iswctype msvcrt.dll 0x000000ed _except_handler3 msvcrt.dll 0x00000274 _wtol msvcrt.dll 0x0000032f wcsncmp msvcrt.dll 0x000001e4 _snwprintf msvcrt.dll 0x00000290 exit msvcrt.dll 0x000000a8 _acmdln msvcrt.dll 0x0000006d __getmainargs msvcrt.dll 0x0000013b _initterm msvcrt.dll 0x0000009a __setusermatherr msvcrt.dll 0x000000b6 _adjust_fdiv msvcrt.dll 0x00000080 __p__commode msvcrt.dll 0x00000085 __p__fmode msvcrt.dll 0x00000098 __set_app_type msvcrt.dll 0x000000d6 _controlfp msvcrt.dll 0x00000330 wcsncpy ADVAPI32.dll 0x000001ef RegQueryValueExW ADVAPI32.dll 0x000001ca RegCloseKey ADVAPI32.dll 0x000001d0 RegCreateKeyW ADVAPI32.dll 0x00000139 IsTextUnicode ADVAPI32.dll 0x000001ee RegQueryValueExA ADVAPI32.dll 0x000001e4 RegOpenKeyExA ADVAPI32.dll 0x000001fc RegSetValueExW KERNEL32.dll 0x0000013e GetCurrentThreadId KERNEL32.dll 0x000001d4 GetTickCount KERNEL32.dll 0x00000294 QueryPerformanceCounter KERNEL32.dll 0x0000016a GetLocalTime KERNEL32.dll 0x000001d8 GetUserDefaultLCID KERNEL32.dll 0x00000140 GetDateFormatW KERNEL32.dll 0x000001d6 GetTimeFormatW KERNEL32.dll 0x000001f8 GlobalLock KERNEL32.dll 0x000001ff GlobalUnlock KERNEL32.dll 0x0000015a GetFileInformationByHandle KERNEL32.dll 0x00000051 CreateFileMappingW KERNEL32.dll 0x000001c0 GetSystemTimeAsFileTime KERNEL32.dll 0x0000034a TerminateProcess KERNEL32.dll 0x0000013b GetCurrentProcess KERNEL32.dll 0x00000336 SetUnhandledExceptionFilter KERNEL32.dll 0x00000244 LoadLibraryA KERNEL32.dll 0x00000176 GetModuleHandleA KERNEL32.dll 0x000001ae GetStartupInfoA KERNEL32.dll 0x000001f4 GlobalFree KERNEL32.dll 0x0000016c GetLocaleInfoW KERNEL32.dll 0x0000024e LocalFree KERNEL32.dll 0x0000024a LocalAlloc KERNEL32.dll 0x000003b8 lstrlenW KERNEL32.dll 0x00000254 LocalUnlock KERNEL32.dll 0x00000038 CompareStringW KERNEL32.dll 0x00000250 LocalLock KERNEL32.dll 0x000000ea FoldStringW KERNEL32.dll 0x00000031 CloseHandle KERNEL32.dll 0x000003b2 lstrcpyW KERNEL32.dll 0x000002a6 ReadFile KERNEL32.dll 0x00000052 CreateFileW KERNEL32.dll 0x000003af lstrcmpiW KERNEL32.dll 0x0000013c GetCurrentProcessId KERNEL32.dll 0x00000198 GetProcAddress KERNEL32.dll 0x0000010a GetCommandLineW KERNEL32.dll 0x000003a9 lstrcatW KERNEL32.dll 0x000000cc FindClose KERNEL32.dll 0x000000d3 FindFirstFileW KERNEL32.dll 0x00000159 GetFileAttributesW KERNEL32.dll 0x000003ac lstrcmpW KERNEL32.dll 0x00000266 MulDiv KERNEL32.dll 0x000003b5 lstrcpynW KERNEL32.dll 0x00000253 LocalSize KERNEL32.dll 0x00000168 GetLastError KERNEL32.dll 0x0000038f WriteFile KERNEL32.dll 0x00000316 SetLastError KERNEL32.dll 0x00000382 WideCharToMultiByte KERNEL32.dll 0x00000251 LocalReAlloc KERNEL32.dll 0x000000ec FormatMessageW KERNEL32.dll 0x000001da GetUserDefaultUILanguage KERNEL32.dll 0x00000300 SetEndOfFile KERNEL32.dll 0x00000082 DeleteFileW KERNEL32.dll 0x000000f6 GetACP KERNEL32.dll 0x0000035e UnmapViewOfFile KERNEL32.dll 0x00000267 MultiByteToWideChar KERNEL32.dll 0x0000025a MapViewOfFile KERNEL32.dll 0x0000035b UnhandledExceptionFilter GDI32.dll 0x00000098 EndPage GDI32.dll 0x00000000 AbortDoc GDI32.dll 0x00000096 EndDoc GDI32.dll 0x0000008c DeleteDC GDI32.dll 0x00000249 StartPage GDI32.dll 0x000001b6 GetTextExtentPoint32W GDI32.dll 0x0000002f CreateDCW GDI32.dll 0x00000211 SetAbortProc GDI32.dll 0x000001bc GetTextFaceW GDI32.dll 0x00000250 TextOutW GDI32.dll 0x00000247 StartDocW GDI32.dll 0x000000ce EnumFontsW GDI32.dll 0x000001a6 GetStockObject GDI32.dll 0x00000198 GetObjectW GDI32.dll 0x0000016c GetDeviceCaps GDI32.dll 0x0000003d CreateFontIndirectW GDI32.dll 0x0000008f DeleteObject GDI32.dll 0x000001be GetTextMetricsW GDI32.dll 0x00000217 SetBkMode GDI32.dll 0x000001cc LPtoDP GDI32.dll 0x00000243 SetWindowExtEx GDI32.dll 0x0000023f SetViewportExtEx GDI32.dll 0x0000022c SetMapMode GDI32.dll 0x0000020f SelectObject USER32.dll 0x000000ff GetClientRect USER32.dll 0x0000024d SetCursor USER32.dll 0x0000022a ReleaseDC USER32.dll 0x0000010c GetDC USER32.dll 0x0000009f DialogBoxParamW USER32.dll 0x00000243 SetActiveWindow USER32.dll 0x00000122 GetKeyboardLayout USER32.dll 0x0000008f DefWindowProcW USER32.dll 0x00000099 DestroyWindow USER32.dll 0x000001db MessageBeep USER32.dll 0x00000292 ShowWindow USER32.dll 0x00000117 GetForegroundWindow USER32.dll 0x000001a6 IsIconic USER32.dll 0x00000173 GetWindowPlacement USER32.dll 0x00000037 CharUpperW USER32.dll 0x000001c9 LoadStringW USER32.dll 0x000001b4 LoadAcceleratorsW USER32.dll 0x0000015c GetSystemMenu USER32.dll 0x00000218 RegisterClassExW USER32.dll 0x000001be LoadImageW USER32.dll 0x000001ba LoadCursorW USER32.dll 0x00000282 SetWindowPlacement USER32.dll 0x00000061 CreateWindowExW USER32.dll 0x0000010e GetDesktopWindow USER32.dll 0x00000116 GetFocus USER32.dll 0x000001bc LoadIconW USER32.dll 0x00000287 SetWindowTextW USER32.dll 0x00000201 PostQuitMessage USER32.dll 0x00000228 RegisterWindowMessageW USER32.dll 0x000002bb UpdateWindow USER32.dll 0x0000026f SetScrollPos USER32.dll 0x00000029 CharLowerW USER32.dll 0x000001fe PeekMessageW USER32.dll 0x000000c4 EnableWindow USER32.dll 0x000000be DrawTextExW USER32.dll 0x00000056 CreateDialogParamW USER32.dll 0x0000017a GetWindowTextW USER32.dll 0x0000015d GetSystemMetrics USER32.dll 0x000001e9 MoveWindow USER32.dll 0x00000193 InvalidateRect USER32.dll 0x000002d3 WinHelpW USER32.dll 0x00000110 GetDlgCtrlID USER32.dll 0x0000003c ChildWindowFromPoint USER32.dll 0x00000231 ScreenToClient USER32.dll 0x0000010b GetCursorPos USER32.dll 0x00000237 SendDlgItemMessageW USER32.dll 0x00000240 SendMessageW USER32.dll 0x0000002c CharNextW USER32.dll 0x00000039 CheckMenuItem USER32.dll 0x00000042 CloseClipboard USER32.dll 0x0000019f IsClipboardFormatAvailable USER32.dll 0x000001f3 OpenClipboard USER32.dll 0x00000137 GetMenuState USER32.dll 0x000000c2 EnableMenuItem USER32.dll 0x00000159 GetSubMenu USER32.dll 0x0000012c GetMenu USER32.dll 0x000001e3 MessageBoxW USER32.dll 0x00000281 SetWindowLongW USER32.dll 0x0000016f GetWindowLongW USER32.dll 0x00000111 GetDlgItem USER32.dll 0x00000256 SetFocus USER32.dll 0x00000254 SetDlgItemTextW USER32.dll 0x000002d9 wsprintfW USER32.dll 0x00000114 GetDlgItemTextW USER32.dll 0x000000c6 EndDialog USER32.dll 0x00000145 GetParent USER32.dll 0x000002ac UnhookWinEvent USER32.dll 0x000000a2 DispatchMessageW USER32.dll 0x000002aa TranslateMessage USER32.dll 0x000002a8 TranslateAcceleratorW USER32.dll 0x000001a2 IsDialogMessageW USER32.dll 0x00000200 PostMessageW USER32.dll 0x0000013e GetMessageW USER32.dll 0x0000027e SetWinEventHook ——————————BOUND IMPORT TABLE—————————— comdlg32.dll SHELL32.dll WINSPOOL.DRV COMCTL32.dll msvcrt.dll ADVAPI32.dll KERNEL32.dll NTDLL.DLL GDI32.dll USER32.dll ——————————Debug Table—————————— The path of PDB : oPテ;E彏踀痳蜎 ——————————RESOURCE TABLE—————————— numEntry1:8 resType0 : 0x3 numEntry2:9 ID:1 numEntry3:1 Rva:0x100b568 size:1640 ID:2 numEntry3:1 Rva:0x100bbd0 size:744 ID:3 numEntry3:1 Rva:0x100beb8 size:296 ID:4 numEntry3:1 Rva:0x100bfe0 size:3752 ID:5 numEntry3:1 Rva:0x100ce88 size:2216 ID:6 numEntry3:1 Rva:0x100d730 size:1384 ID:7 numEntry3:1 Rva:0x100dc98 size:9640 ID:8 numEntry3:1 Rva:0x1010240 size:4264 ID:9 numEntry3:1 Rva:0x10112e8 size:1128 resType1 : 0x4 numEntry2:1 ID:1 numEntry3:1 Rva:0x1011750 size:816 resType2 : 0x5 numEntry2:4 Name:N numEntry3:1 Rva:0x1011780 size:816 ID:11 numEntry3:1 Rva:0x10117fc size:816 ID:12 numEntry3:1 Rva:0x1011bbc size:1128 ID:14 numEntry3:1 Rva:0x1012024 size:208 resType3 : 0x6 numEntry2:4 ID:1 numEntry3:1 Rva:0x10120f4 size:668 ID:2 numEntry3:1 Rva:0x1012390 size:700 ID:3 numEntry3:1 Rva:0x101264c size:232 ID:30 numEntry3:1 Rva:0x1012734 size:40 resType4 : 0x9 numEntry2:2 Name:M numEntry3:1 Rva:0x101275c size:136 Name:S numEntry3:1 Rva:0x10127e4 size:168 resType5 : 0xe numEntry2:1 ID:2 numEntry3:1 Rva:0x101288c size:132 resType6 : 0x10 numEntry2:1 ID:1 numEntry3:1 Rva:0x1012910 size:880 resType7 : 0x18 numEntry2:1 ID:1 numEntry3:1 Rva:0x1012c80 size:670 |
|
[原创]自己写的PE分析工具(附源代码)
ParsePE.h #pragma once #include <Windows.h> #include <assert.h> #include <iostream> #include <vector> using namespace std; //导出表函数 typedef struct _FUNCEXPINFO { UINT rva; //相对虚拟地址 UINT ordinal; //序号 string name; //名称 }FUNCEXPINFO; //导入表函数 typedef struct _FUNCIMPINFO { string dllName; //DLL名称 UINT ordinal; //在对应的DLL输出表的序号 string funcName; //导入函数名称 }FUNCIMPINFO; typedef struct _PEINFO { bool bDLL; long imageBase; long entryPoint; long dosRVA; long dosSize; long pNtHeader; long numSections; long sectionAlign; long fileAlign; }PEINFO; class CParsePE { public: CParsePE(const wchar_t *pFileName) { assert(0 != pFileName); m_PeInfo.imageBase = 0; errno_t err; if ((err = _wfopen_s(&fp, pFileName, L"r")) != 0) { cout<<"The file '"<<pFileName<<"'"<<"was not opened!"<<endl; } if (!is_pe_file()) { cout<<"is not pe file!"<<endl; } } ~CParsePE(void) { if (fp != 0) { fclose(fp); } } public: bool is_pe_file(); bool findIsFunc(UINT rva, UINT ordinal); void ParseSections(); void ParseDosHeader(); void ParseNtHeader(); void ParseExportTable(); void ParseImportTable(); void ParseBoundImportTable(); void ParseDelayImportTable(); void ParseDebugTable(); void ParseResouceTable(); UINT VAToRawAddr(UINT virtualAddr); void DisplayPEInfo(); public: //void printExportTable(FUNCINFO funcInfo); private: PEINFO m_PeInfo; FILE *fp; IMAGE_DOS_HEADER m_dosHeader; IMAGE_NT_HEADERS m_ntHeader; IMAGE_FILE_HEADER m_fileHeader; IMAGE_OPTIONAL_HEADER m_opHeader; IMAGE_SECTION_HEADER m_secHeader; IMAGE_DATA_DIRECTORY m_dataDir; IMAGE_IMPORT_DESCRIPTOR m_importDir; IMAGE_EXPORT_DIRECTORY m_exportDir; IMAGE_RESOURCE_DIRECTORY m_resourceDir; IMAGE_TLS_DIRECTORY m_tlsDir; private: vector<UINT> m_vSectionVirtualAddress; //块的起始地址VA vector<UINT> m_vSectionVirtualSize; //块的大小(包含块的间隙) vector<UINT> m_vSectionRawAddress; //块的其实地址(在物理文件中) vector<UINT> m_vSectionRawSize; //块的大小(物理文件中) private: vector<FUNCEXPINFO> m_vExportFunc; vector<FUNCIMPINFO> m_vImportFunc; vector<FUNCIMPINFO> m_vDelayImportFunc; int m_NumImportDll; }; |
|
[原创]自己写的PE分析工具(附源代码)
ParsePE.cpp #include "StdAfx.h" #include "ParsePE.h" #include <algorithm> #include <delayimp.h> typedef ImgDelayDescr IMAGE_DELAY_IMPORT_DESCRIPTOR; extern FILE *pFResult; //调试时才打印该信息,必要的时候也可以打印到文件中去 inline void DebugPrint(const char *vmf, ...) { #ifdef _DEBUG va_list ap; va_start(ap, vmf); vprintf(vmf, ap); vfprintf(pFResult, vmf, ap); va_end(ap); #endif } //判断是否是PE文件格式,两个地方:1.DOS块标识e_magic;2.PE文件头标识signature bool CParsePE::is_pe_file() { WORD dosMagic; //DOS MZ Header的标识符 DWORD peMagic; //PE文件头的标识符 long peStaAddr; fseek(fp, 0, 0); fread_s(&dosMagic, sizeof(dosMagic), sizeof(WORD), 1, fp); fseek(fp, 60, 0); fread_s(&peStaAddr, sizeof(peStaAddr), sizeof(long), 1, fp); fseek(fp, peStaAddr, 0); fread_s(&peMagic, sizeof(peMagic), sizeof(DWORD), 1, fp); if (IMAGE_DOS_SIGNATURE != dosMagic || IMAGE_NT_SIGNATURE != peMagic) { return false; } return true; } //解析DOS MZ部首 void CParsePE::ParseDosHeader() { LONG lfanew; fseek(fp, 0, 0); fread_s(&m_dosHeader, sizeof(m_dosHeader), sizeof(IMAGE_DOS_HEADER), 1, fp); fseek(fp, 60, 0); fread_s(&lfanew, sizeof(lfanew), sizeof(LONG), 1, fp); m_PeInfo.pNtHeader = m_PeInfo.imageBase + lfanew; m_PeInfo.dosRVA = m_PeInfo.imageBase; m_PeInfo.dosSize = m_PeInfo.pNtHeader - m_PeInfo.imageBase; //打印DOS MZ部首信息 DebugPrint("\n——————————Dos Header Info——————————\n"\ "dos RVA : 0x%08x\n"\ "dos size : 0x%08x\n", m_PeInfo.dosRVA, m_PeInfo.dosSize); } //解析PE文件头 void CParsePE::ParseNtHeader() { fseek(fp, m_PeInfo.pNtHeader, 0); fread_s(&m_ntHeader, sizeof(m_ntHeader), sizeof(IMAGE_NT_HEADERS), 1, fp); m_fileHeader = m_ntHeader.FileHeader; m_opHeader = m_ntHeader.OptionalHeader; //映象文件头 m_PeInfo.bDLL = m_fileHeader.Characteristics & IMAGE_FILE_DLL != 0 ? true : false; m_PeInfo.numSections = m_fileHeader.NumberOfSections; //可选映象头 m_PeInfo.sectionAlign = m_opHeader.SectionAlignment; m_PeInfo.fileAlign = m_opHeader.FileAlignment; m_PeInfo.entryPoint = m_opHeader.AddressOfEntryPoint; m_PeInfo.imageBase = m_opHeader.ImageBase; int curSecOffset = m_PeInfo.pNtHeader + sizeof(IMAGE_NT_HEADERS); IMAGE_SECTION_HEADER sectionHeader; DebugPrint("\n——————————sections Info——————————\n"); for (int i = 0; i < m_PeInfo.numSections; i++) { fseek(fp, curSecOffset + i * sizeof(IMAGE_SECTION_HEADER), 0); fread_s(§ionHeader, sizeof(IMAGE_SECTION_HEADER), sizeof(IMAGE_SECTION_HEADER), 1, fp); m_vSectionVirtualAddress.push_back(sectionHeader.VirtualAddress); m_vSectionVirtualSize.push_back(sectionHeader.Misc.VirtualSize);//实际的大小 //如果有空隙,加上空隙 if (m_vSectionVirtualSize[i]%m_PeInfo.sectionAlign != 0) { UINT interspace = m_PeInfo.sectionAlign - m_vSectionVirtualSize[i]%m_PeInfo.sectionAlign; m_vSectionVirtualSize[i] += interspace; } m_vSectionRawAddress.push_back(sectionHeader.PointerToRawData); m_vSectionRawSize.push_back(sectionHeader.SizeOfRawData); DebugPrint("section name : %s\n"\ "VirtualAddress : 0x%08x\n"\ "VirtualSize : 0x%08x\n"\ "RawAddress : 0x%08x\n"\ "RwaSize : 0x%08x\n", sectionHeader.Name, sectionHeader.VirtualAddress, m_vSectionVirtualSize[i], m_vSectionRawAddress[i], m_vSectionRawSize[i]); } DebugPrint("\n——————————Header Info——————————\n"\ "imageBase : 0x%08x\n"\ "entryPoint : 0x%08x\n"\ "sectionAlignment : 0x%08x\n"\ "fileAlignment : 0x%08x\n"\ "numSections : 0x%08x\n", m_PeInfo.imageBase, m_PeInfo.entryPoint, m_PeInfo.sectionAlign, m_PeInfo.fileAlign, m_vSectionRawAddress.size()); ParseExportTable(); } //解析各个节 void CParsePE::ParseSections() { IMAGE_SECTION_HEADER sectionHeader; for (int i = 0; i < m_PeInfo.numSections; i++) { } } //虚拟地址转换为物理地址 UINT CParsePE::VAToRawAddr( UINT virtualAddr ) { assert(virtualAddr); if (m_PeInfo.numSections > 0 && virtualAddr < m_vSectionVirtualAddress[0]) { return virtualAddr; } for (int i = 0; i < m_PeInfo.numSections; i++) { if (virtualAddr >= m_vSectionVirtualAddress[i] && virtualAddr < m_vSectionVirtualAddress[i] + m_vSectionVirtualSize[i]) { return virtualAddr - (m_vSectionVirtualAddress[i] - m_vSectionRawAddress[i]); } } return -1; } //查找是否在m_vExportFunc中 bool CParsePE::findIsFunc(UINT rva, UINT ordinal) { assert(ordinal >= 0); assert(rva >= 0); for (int i = 0; i < m_vExportFunc.size(); i++) { if (m_vExportFunc.at(i).ordinal == ordinal) { m_vExportFunc.at(i).rva = rva; return true; } } FUNCEXPINFO funcInfo = {0}; funcInfo.rva = rva; funcInfo.ordinal = ordinal; m_vExportFunc.push_back(funcInfo); return true; } //打印输出表信息 void printExportTable(FUNCEXPINFO funcInfo) { DebugPrint("0x%08x\t0x%08x\t%s\n", funcInfo.rva, funcInfo.ordinal, funcInfo.name.c_str()); } //打印输入表信息 void printImportTable(FUNCIMPINFO funcImpInfo) { DebugPrint("%s\t0x%08x\t%s\n", funcImpInfo.dllName.c_str(), funcImpInfo.ordinal, funcImpInfo.funcName.c_str()); } //解析输出表 void CParsePE::ParseExportTable() { IMAGE_DATA_DIRECTORY dataDir; dataDir = m_opHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; if (dataDir.Size != 0) { UINT exportStartAddr = VAToRawAddr(dataDir.VirtualAddress); fseek(fp, exportStartAddr, 0); fread_s(&m_exportDir, sizeof(m_exportDir), sizeof(IMAGE_EXPORT_DIRECTORY), 1, fp); UINT nameStartAddr = VAToRawAddr(m_exportDir.AddressOfNames); for (int i = 0; i < m_exportDir.NumberOfNames; i++) { FUNCEXPINFO funcInfo = {0}; char FuncName[40] = {0}; assert(m_exportDir.AddressOfNames != 0); //ENT UINT nameRVA = m_exportDir.AddressOfNames + i * sizeof(DWORD); UINT nameFileAddr = VAToRawAddr(nameRVA); UINT nameRVA2; UINT nameFileAddr2; fseek(fp, nameFileAddr, 0); fread_s(&nameRVA2, sizeof(nameRVA2), sizeof(UINT), 1, fp); nameFileAddr2 = VAToRawAddr(nameRVA2); fseek(fp, nameFileAddr2, 0); fread_s(&FuncName, sizeof(FuncName), 40, 1, fp); funcInfo.name.assign(FuncName); //ENT对应的序号表 UINT ordinalRVA = m_exportDir.AddressOfNameOrdinals + i * sizeof(WORD); UINT ordinalFileAddr = VAToRawAddr(ordinalRVA); short int ordinal; fseek(fp, ordinalFileAddr, 0); fread_s(&ordinal, sizeof(ordinal), sizeof(WORD), 1, fp); funcInfo.ordinal = ordinal; m_vExportFunc.push_back(funcInfo); } //查找EAT,并找出以序号输出的函数 for (int i = 0; i < m_exportDir.NumberOfFunctions; i++) { UINT funcAddr = m_exportDir.AddressOfFunctions + i*sizeof(DWORD); UINT funcFileAddr = VAToRawAddr(funcAddr); UINT rva; UINT ordinal = m_exportDir.Base + i;//当前输出函数的序号 fseek(fp, funcFileAddr, 0); fread_s(&rva, sizeof(rva), sizeof(DWORD), 1, fp); //如果不是名称,那么它一定是以序号输出的 findIsFunc(rva, ordinal); } //打印输出表信息 DebugPrint("\n\n\n——————————Export Table——————————\n"); for_each(m_vExportFunc.begin(), m_vExportFunc.end(), printExportTable); } } //解析输入表 void CParsePE::ParseImportTable() { IMAGE_THUNK_DATA32 thunkData; IMAGE_DATA_DIRECTORY dataDir; IMAGE_IMPORT_DESCRIPTOR importTable; char dllName[56] = {'0'}; dataDir = m_opHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; if (dataDir.VirtualAddress) { UINT curFileAddr = VAToRawAddr(dataDir.VirtualAddress); fseek(fp, curFileAddr, 0); fread_s(&importTable, sizeof(importTable), sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, fp); m_NumImportDll = 0; while(importTable.FirstThunk) { m_NumImportDll++; //获取导入库的名称 UINT dllNameFileAddr = VAToRawAddr(importTable.Name); fseek(fp, dllNameFileAddr, 0); fread_s(&dllName, sizeof(dllName), sizeof(dllName), 1, fp); UINT originalRawAddr = VAToRawAddr(importTable.OriginalFirstThunk); fseek(fp, originalRawAddr, 0); fread_s(&thunkData, sizeof(thunkData), sizeof(IMAGE_THUNK_DATA), 1, fp); unsigned int k = 0; while(thunkData.u1.AddressOfData) { FUNCIMPINFO funcImpInfo; funcImpInfo.dllName.assign(dllName); if (thunkData.u1.Ordinal & 0x80000000) //如果最高位为1,那么函数是以序号导入的 { funcImpInfo.ordinal = thunkData.u1.Ordinal & 0x7fffffff; } else //如果是名字输出,那么该地址是指向IMAGE_IMPORT_BY_NAME的RVA { IMAGE_IMPORT_BY_NAME importByName; char funcName[50] = {'0'}; UINT nameFuncAddr = VAToRawAddr(thunkData.u1.AddressOfData); fseek(fp, nameFuncAddr, 0); fread_s(&importByName, sizeof(importByName), sizeof(IMAGE_IMPORT_BY_NAME), 1, fp); funcImpInfo.ordinal = importByName.Hint; fseek(fp, nameFuncAddr + 2, 0); fread_s(funcName, sizeof(funcName), sizeof(funcName), 1, fp); funcImpInfo.funcName.assign(funcName); } m_vImportFunc.push_back(funcImpInfo); fseek(fp, originalRawAddr + (++k) * sizeof(IMAGE_THUNK_DATA), 0); fread_s(&thunkData, sizeof(thunkData), sizeof(IMAGE_THUNK_DATA), 1, fp); } fseek(fp, curFileAddr + m_NumImportDll * sizeof(IMAGE_IMPORT_DESCRIPTOR), 0); fread_s(&importTable, sizeof(importTable), sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, fp); } //打印输入表信息 DebugPrint("\n\n\n——————————Import Table——————————\n"); for_each(m_vImportFunc.begin(), m_vImportFunc.end(), printImportTable); } } //解析延迟输入表 void CParsePE::ParseDelayImportTable() { IMAGE_THUNK_DATA32 thunkData; IMAGE_DATA_DIRECTORY dataDir; IMAGE_DELAY_IMPORT_DESCRIPTOR importTable; char dllName[56] = {'0'}; dataDir = m_opHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]; if (dataDir.VirtualAddress > 0) { UINT curFileAddr = VAToRawAddr(dataDir.VirtualAddress); fseek(fp, curFileAddr, 0); fread_s(&importTable, sizeof(importTable), sizeof(IMAGE_DELAY_IMPORT_DESCRIPTOR), 1, fp); m_NumImportDll = 0; while(importTable.rvaIAT) { m_NumImportDll++; //获取导入库的名称 UINT dllNameFileAddr = VAToRawAddr(importTable.rvaDLLName); fseek(fp, dllNameFileAddr, 0); fread_s(&dllName, sizeof(dllName), sizeof(dllName), 1, fp); UINT originalRawAddr = VAToRawAddr(importTable.rvaINT); fseek(fp, originalRawAddr, 0); fread_s(&thunkData, sizeof(thunkData), sizeof(IMAGE_THUNK_DATA), 1, fp); unsigned int k = 0; while(thunkData.u1.AddressOfData) { FUNCIMPINFO funcImpInfo; funcImpInfo.dllName.assign(dllName); if (thunkData.u1.Ordinal & 0x80000000) //如果最高位为1,那么函数是以序号导入的 { funcImpInfo.ordinal = thunkData.u1.Ordinal & 0x7fffffff; } else //如果是名字输出,那么该地址是指向IMAGE_IMPORT_BY_NAME的RVA { IMAGE_IMPORT_BY_NAME importByName; char funcName[50] = {'0'}; UINT nameFuncAddr = VAToRawAddr(thunkData.u1.AddressOfData); fseek(fp, nameFuncAddr, 0); fread_s(&importByName, sizeof(importByName), sizeof(IMAGE_IMPORT_BY_NAME), 1, fp); funcImpInfo.ordinal = importByName.Hint; fseek(fp, nameFuncAddr + 2, 0); fread_s(funcName, sizeof(funcName), sizeof(funcName), 1, fp); funcImpInfo.funcName.assign(funcName); } m_vDelayImportFunc.push_back(funcImpInfo); fseek(fp, originalRawAddr + (++k) * sizeof(IMAGE_THUNK_DATA), 0); fread_s(&thunkData, sizeof(thunkData), sizeof(IMAGE_THUNK_DATA), 1, fp); } fseek(fp, curFileAddr + m_NumImportDll * sizeof(IMAGE_DELAY_IMPORT_DESCRIPTOR), 0); fread_s(&importTable, sizeof(importTable), sizeof(IMAGE_DELAY_IMPORT_DESCRIPTOR), 1, fp); } //打印输入表信息 DebugPrint("\n\n\n——————————Delay Import Table——————————\n"); for_each(m_vDelayImportFunc.begin(), m_vDelayImportFunc.end(), printImportTable); } } //解析绑定输入表 void CParsePE::ParseBoundImportTable() { IMAGE_DATA_DIRECTORY dataDir; IMAGE_BOUND_IMPORT_DESCRIPTOR boundImportTable; IMAGE_BOUND_FORWARDER_REF boundForRef; char dllName[56] = {'0'}; dataDir = m_opHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]; if (dataDir.VirtualAddress) { DebugPrint("\n\n\n——————————BOUND IMPORT TABLE——————————\n"); UINT curFileAddr = VAToRawAddr(dataDir.VirtualAddress); fseek(fp, curFileAddr, 0); fread_s(&boundImportTable, sizeof(boundImportTable), sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR), 1, fp); UINT k = 0; while(boundImportTable.OffsetModuleName) { fseek(fp, curFileAddr + boundImportTable.OffsetModuleName, 0); fread_s(&dllName, sizeof(dllName), 56, 1, fp); DebugPrint("%s\t", dllName); for (int i = 0; i < boundImportTable.NumberOfModuleForwarderRefs; i++) { fseek(fp, curFileAddr + (++k) * sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR), 0); fread_s(&boundImportTable, sizeof(boundImportTable), sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR), 1, fp); fseek(fp, curFileAddr + boundImportTable.OffsetModuleName, 0); fread_s(&dllName, sizeof(dllName), 56, 1, fp); DebugPrint("%s\t", dllName); } fseek(fp, curFileAddr + (++k) * sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR), 0); fread_s(&boundImportTable, sizeof(boundImportTable), sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR), 1, fp); } } //boundImportTable.OffsetModuleName } //解析DEBUG目录表 void CParsePE::ParseDebugTable() { IMAGE_DATA_DIRECTORY debugDir; IMAGE_DEBUG_DIRECTORY debugTable; char pdbName[128]; debugDir = m_opHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; if (debugDir.VirtualAddress) { UINT curFileAddr = VAToRawAddr(debugDir.VirtualAddress); fseek(fp, curFileAddr, 0); fread_s(&debugTable, sizeof(debugTable), sizeof(IMAGE_DEBUG_DIRECTORY), 1, fp); if (IMAGE_DEBUG_TYPE_CODEVIEW == debugTable.Type) { fseek(fp, debugTable.PointerToRawData + 6, 0); fread_s(&pdbName, sizeof(pdbName), 128, 1, fp); DebugPrint("\n\n\n——————————Debug Table——————————\n"\ "The path of PDB : %s", pdbName); } } } //解析RESOURSE目录表 void CParsePE::ParseResouceTable() { IMAGE_DATA_DIRECTORY resDir; IMAGE_RESOURCE_DIRECTORY resTable; IMAGE_RESOURCE_DIRECTORY_ENTRY resEntryTable; resDir = m_opHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; if (resDir.VirtualAddress) { DebugPrint("\n\n\n——————————RESOURCE TABLE——————————\n"); UINT curFileAddr = VAToRawAddr(resDir.VirtualAddress); fseek(fp, curFileAddr, 0); fread_s(&resTable, sizeof(resTable), sizeof(IMAGE_RESOURCE_DIRECTORY), 1, fp); UINT numEntry = resTable.NumberOfIdEntries + resTable.NumberOfNamedEntries; DebugPrint("numEntry1:%d\n", numEntry); //第一层目录 //定义的是资源类型 for (int i = 0; i < numEntry; i++) { fseek(fp, curFileAddr + sizeof(IMAGE_RESOURCE_DIRECTORY) + i * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 0); fread_s(&resEntryTable, sizeof(resEntryTable), sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, fp); //资源类型的ID //01 Cursor 08 Font(字体) //02 Bitmap 09 Accelerators(加速键) //03 Icon 0A Unformatted(未格式资源) //04 Menu 0B MessageTable(消息表) //05 Dialog 0C Group Cursor(光标组) //06 String 0E Group Icon(图标组) //07 Font Directory 10 Versoin Information(版本信息) DebugPrint("\nresType%d : 0x%x\n", i, resEntryTable.Id); //是否低位数据指向下一层目录块的起始地址 if (resEntryTable.DataIsDirectory) { IMAGE_RESOURCE_DIRECTORY resTable2; fseek(fp, curFileAddr + resEntryTable.OffsetToDirectory, 0); fread_s(&resTable2, sizeof(resTable2), sizeof(IMAGE_RESOURCE_DIRECTORY), 1, fp); UINT numEntry2 = resTable2.NumberOfIdEntries + resTable2.NumberOfNamedEntries; DebugPrint("numEntry2:%d\n", numEntry2); //第二层目录 //定义的是资源的名称 for (int j = 0; j < numEntry2; j++) { IMAGE_RESOURCE_DIRECTORY_ENTRY resEntryTable2; fseek(fp, curFileAddr + resEntryTable.OffsetToDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY) + j * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 0); fread_s(&resEntryTable2, sizeof(resEntryTable2), sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, fp); //第二层的NAME字段是目录项的名称字符串指针,否则用ID号表示 if (resEntryTable2.NameIsString) { IMAGE_RESOURCE_DIR_STRING_U dirStr; fseek(fp, curFileAddr + resEntryTable2.NameOffset, 0); fread_s(&dirStr, sizeof(resDir), sizeof(IMAGE_RESOURCE_DIR_STRING_U), 1, fp); DebugPrint("Name:%s\n", dirStr.NameString); } else { DebugPrint("ID:%d\n", resEntryTable2.NameOffset); } //最高位为1时,指向下一层目录块的起始地址,否则指针指向IMAGE_RESOURCE_DATA_ENTRY if (resEntryTable2.DataIsDirectory) { IMAGE_RESOURCE_DIRECTORY resTable3; fseek(fp, curFileAddr + resEntryTable2.OffsetToDirectory, 0); fread_s(&resTable3, sizeof(resTable3), sizeof(IMAGE_RESOURCE_DIRECTORY), 1, fp); UINT numEntry3 = resTable3.NumberOfIdEntries + resTable3.NumberOfNamedEntries; DebugPrint("numEntry3:%d\n", numEntry3); //第三层 //定义的是代码页编号 for (int k = 0; k < numEntry3; k++) { IMAGE_RESOURCE_DIRECTORY_ENTRY resEntryTable3; fseek(fp, curFileAddr + resEntryTable2.OffsetToDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY) + k * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 0); fread_s(&resEntryTable3, sizeof(resEntryTable3), sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, fp); if (!resEntryTable3.DataIsDirectory) { IMAGE_RESOURCE_DATA_ENTRY resDirEntry; fseek(fp, curFileAddr + resEntryTable3.OffsetToDirectory, 0); fread_s(&resDirEntry, sizeof(resDirEntry), sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, fp); DebugPrint("Rva:0x%x\t", resDirEntry.OffsetToData + m_PeInfo.imageBase); DebugPrint("size:%d\n", resDirEntry.Size); } else { _asm int 3 } } } else { IMAGE_RESOURCE_DATA_ENTRY resDirEntry; fseek(fp, curFileAddr + resEntryTable2.OffsetToDirectory, 0); fread_s(&resDirEntry, sizeof(resDirEntry), sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, fp); DebugPrint("Rva:0x%x\t", resDirEntry.OffsetToData + m_PeInfo.imageBase); DebugPrint("size:%d\n", resDirEntry.Size); } } } } } } void CParsePE::DisplayPEInfo() { } |
|
病毒分析入门
多谢!!!能不能给点详细明确的提示??? |
|
病毒分析入门
是哪个网站??? |
|
求爆破方法
那个壳挺强大的 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值