如何让披了外壳的样例露出真身,让IDA对其真身分析
脱壳准备工作,IDA静态分析半自动完成以下函数集静态变量重命名,
其中得到导入表位置,通过IDAPython自动生成OD Script修复IAT,
最后通过IMportRec重新建立导入表
00444108 Hi_crtmain
004442A2 Hi_start
00444509 Hi_Init_UnhandledExceptionFilter
00444515 Hi_UnhandledExceptionFilter
004447BD Hi_security_cookie_init
00489008 Hi_security_cook_not
0048900C Hi_security_cook
004A9B88 Hi_init0
004AD000 Hi_fp_ADVAPI32_RegOpenKeyExW_4AD000
004AD004 Hi_fp_ADVAPI32_RegDeleteValueW_4AD004
004AD008 Hi_fp_ADVAPI32_RegCreateKeyExW_4AD008
004AD00C Hi_fp_ADVAPI32_RegSetValueExW_4AD00C
004AD010 Hi_fp_ADVAPI32_RegDeleteKeyW_4AD010
004AD014 Hi_fp_ADVAPI32_RegEnumKeyExW_4AD014
004AD018 Hi_fp_ADVAPI32_RegQueryInfoKeyW_4AD018
004AD01C Hi_fp_ADVAPI32_RegCloseKey_4AD01C
004AD024 Hi_fp_COMCTL32_InitCommonControlsEx_4AD024
004AD02C Hi_fp_KERNEL32_VirtualAlloc_4AD02C
004AD030 Hi_fp_KERNEL32_ExitProcess_4AD030
004AD034 Hi_fp_KERNEL32_FreeLibrary_4AD034
004AD038 Hi_fp_KERNEL32_GetProcAddress_4AD038
004AD03C Hi_fp_KERNEL32_lstrcmpiW_4AD03C
004AD040 Hi_fp_KERNEL32_LeaveCriticalSection_4AD040
004AD044 Hi_fp_KERNEL32_RaiseException_4AD044
004AD048 Hi_fp_KERNEL32_EnterCriticalSection_4AD048
004AD04C Hi_fp_KERNEL32_GetLastError_4AD04C
004AD050 Hi_fp_KERNEL32_MultiByteToWideChar_4AD050
004AD054 Hi_fp_KERNEL32_SizeofResource_4AD054
004AD058 Hi_fp_KERNEL32_LoadResource_4AD058
004AD05C Hi_fp_KERNEL32_FindResourceW_4AD05C
004AD060 Hi_fp_KERNEL32_LoadLibraryExW_4AD060
004AD064 Hi_fp_KERNEL32_GetModuleFileNameW_4AD064
004AD068 Hi_fp_KERNEL32_InitializeCriticalSectionAndSpinCount_4AD068
004AD06C Hi_fp_KERNEL32_DeleteCriticalSection_4AD06C
004AD070 Hi_fp_KERNEL32_InterlockedDecrement_4AD070
004AD074 Hi_fp_KERNEL32_InterlockedIncrement_4AD074
004AD078 Hi_fp_KERNEL32_GetCurrentThreadId_4AD078
004AD07C Hi_fp_KERNEL32_DecodePointer_4AD07C
004AD080 Hi_fp_KERNEL32_SetLastError_4AD080
004AD084 Hi_fp_KERNEL32_InitializeCriticalSection_4AD084
004AD088 Hi_fp_KERNEL32_GetCurrentThread_4AD088
004AD08C Hi_fp_KERNEL32_GetThreadContext_4AD08C
004AD090 Hi_fp_KERNEL32_CreateFileW_4AD090
004AD094 Hi_fp_KERNEL32_WideCharToMultiByte_4AD094
004AD098 Hi_fp_KERNEL32_GetUserDefaultLangID_4AD098
004AD09C Hi_fp_KERNEL32_lstrcatA_4AD09C
004AD0A0 Hi_fp_KERNEL32_lstrlenA_4AD0A0
004AD0A4 Hi_fp_KERNEL32_WaitForSingleObject_4AD0A4
004AD0A8 Hi_fp_KERNEL32_CloseHandle_4AD0A8
004AD0AC Hi_fp_KERNEL32_CreateThread_4AD0AC
004AD0B0 Hi_fp_KERNEL32_SetThreadPriority_4AD0B0
004AD0B4 Hi_fp_KERNEL32_HeapAlloc_4AD0B4
004AD0B8 Hi_fp_KERNEL32_HeapCreate_4AD0B8
004AD0BC Hi_fp_KERNEL32_HeapDestroy_4AD0BC
004AD0C0 Hi_fp_KERNEL32_Sleep_4AD0C0
004AD0C4 Hi_fp_KERNEL32_CreateFileA_4AD0C4
004AD0C8 Hi_fp_KERNEL32_ReadFile_4AD0C8
004AD0CC Hi_fp_KERNEL32_SetFilePointer_4AD0CC
004AD0D0 Hi_fp_KERNEL32_FindResourceA_4AD0D0
004AD0D4 Hi_fp_KERNEL32_GetOEMCP_4AD0D4
004AD0D8 Hi_fp_KERNEL32_IsValidCodePage_4AD0D8
004AD0DC Hi_fp_KERNEL32_GetCurrentProcess_4AD0DC
004AD0E0 Hi_fp_KERNEL32_FindNextFileA_4AD0E0
004AD0E4 Hi_fp_KERNEL32_FindFirstFileExW_4AD0E4
004AD0E8 Hi_fp_KERNEL32_FindFirstFileExA_4AD0E8
004AD0EC Hi_fp_KERNEL32_FindClose_4AD0EC
004AD0F0 Hi_fp_KERNEL32_EnumSystemLocalesW_4AD0F0
004AD0F4 Hi_fp_KERNEL32_GetUserDefaultLCID_4AD0F4
004AD0F8 Hi_fp_KERNEL32_IsValidLocale_4AD0F8
004AD0FC Hi_fp_KERNEL32_GetLocaleInfoW_4AD0FC
004AD100 Hi_fp_KERNEL32_LCMapStringW_4AD100
004AD104 Hi_fp_KERNEL32_CompareStringW_4AD104
004AD108 Hi_fp_KERNEL32_GetTimeFormatW_4AD108
004AD10C Hi_fp_KERNEL32_GetDateFormatW_4AD10C
004AD110 Hi_fp_KERNEL32_ReadConsoleW_4AD110
004AD114 Hi_fp_KERNEL32_GetConsoleMode_4AD114
004AD118 Hi_fp_KERNEL32_SetConsoleCtrlHandler_4AD118
004AD11C Hi_fp_KERNEL32_HeapReAlloc_4AD11C
004AD120 Hi_fp_KERNEL32_HeapSize_4AD120
004AD124 Hi_fp_KERNEL32_GetACP_4AD124
004AD128 Hi_fp_KERNEL32_WriteFile_4AD128
004AD12C Hi_fp_KERNEL32_GetStdHandle_4AD12C
004AD130 Hi_fp_KERNEL32_GetModuleFileNameA_4AD130
004AD134 Hi_fp_KERNEL32_GetModuleHandleExW_4AD134
004AD138 Hi_fp_KERNEL32_RtlUnwind_4AD138
004AD13C Hi_fp_KERNEL32_TlsFree_4AD13C
004AD140 Hi_fp_KERNEL32_TlsSetValue_4AD140
004AD144 Hi_fp_KERNEL32_TlsGetValue_4AD144
004AD148 Hi_fp_KERNEL32_TlsAlloc_4AD148
004AD14C Hi_fp_KERNEL32_InterlockedFlushSList_4AD14C
004AD150 Hi_fp_KERNEL32_GetCPInfo_4AD150
004AD154 Hi_fp_KERNEL32_TerminateProcess_4AD154
004AD158 Hi_fp_KERNEL32_GetSystemTimeAsFileTime_4AD158
004AD15C Hi_fp_KERNEL32_GetCurrentProcessId_4AD15C
004AD160 Hi_fp_KERNEL32_QueryPerformanceCounter_4AD160
004AD164 Hi_fp_KERNEL32_GetStartupInfoW_4AD164
004AD168 Hi_fp_KERNEL32_SetUnhandledExceptionFilter_4AD168
004AD16C Hi_fp_KERNEL32_UnhandledExceptionFilter_4AD16C
004AD170 Hi_fp_KERNEL32_GetModuleHandleW_4AD170
004AD174 Hi_fp_KERNEL32_VirtualFree_4AD174
004AD178 Hi_fp_KERNEL32_OutputDebugStringA_4AD178
004AD17C Hi_fp_KERNEL32_SetStdHandle_4AD17C
004AD180 Hi_fp_KERNEL32_GetStringTypeW_4AD180
004AD184 Hi_fp_KERNEL32_SetFilePointerEx_4AD184
004AD188 Hi_fp_KERNEL32_FlushFileBuffers_4AD188
004AD18C Hi_fp_KERNEL32_GetConsoleCP_4AD18C
004AD190 Hi_fp_KERNEL32_SetEndOfFile_4AD190
004AD194 Hi_fp_KERNEL32_GetFileType_4AD194
004AD198 Hi_fp_KERNEL32_SetEnvironmentVariableW_4AD198
004AD19C Hi_fp_KERNEL32_SetEnvironmentVariableA_4AD19C
004AD1A0 Hi_fp_KERNEL32_FreeEnvironmentStringsW_4AD1A0
004AD1A4 Hi_fp_KERNEL32_GetEnvironmentStringsW_4AD1A4
004AD1A8 Hi_fp_KERNEL32_GetCommandLineW_4AD1A8
004AD1AC Hi_fp_KERNEL32_GetCommandLineA_4AD1AC
004AD1B0 Hi_fp_KERNEL32_CreateEventW_4AD1B0
004AD1B4 Hi_fp_KERNEL32_WaitForSingleObjectEx_4AD1B4
004AD1B8 Hi_fp_KERNEL32_ResetEvent_4AD1B8
004AD1BC Hi_fp_KERNEL32_FindNextFileW_4AD1BC
004AD1C0 Hi_fp_KERNEL32_WriteConsoleW_4AD1C0
004AD1C4 Hi_fp_KERNEL32_SetEvent_4AD1C4
004AD1C8 Hi_fp_KERNEL32_LoadLibraryExA_4AD1C8
004AD1CC Hi_fp_KERNEL32_IsDebuggerPresent_4AD1CC
004AD1D0 Hi_fp_KERNEL32_OutputDebugStringW_4AD1D0
004AD1D4 Hi_fp_KERNEL32_EncodePointer_4AD1D4
004AD1D8 Hi_fp_KERNEL32_HeapFree_4AD1D8
004AD1DC Hi_fp_KERNEL32_GetProcessHeap_4AD1DC
004AD1E0 Hi_fp_KERNEL32_InitializeSListHead_4AD1E0
004AD1E4 Hi_fp_KERNEL32_InterlockedPopEntrySList_4AD1E4
004AD1E8 Hi_fp_KERNEL32_InterlockedPushEntrySList_4AD1E8
004AD1EC Hi_fp_KERNEL32_FlushInstructionCache_4AD1EC
004AD1F0 Hi_fp_KERNEL32_IsProcessorFeaturePresent_4AD1F0
004AD1F8 Hi_fp_OLEAUT32_SysFreeString_4AD1F8
004AD1FC Hi_fp_OLEAUT32_VarUI4FromStr_4AD1FC
004AD204 Hi_fp_PSAPI_GetModuleInformation_4AD204
004AD20C Hi_fp_USER32_MessageBoxW_4AD20C
004AD210 Hi_fp_USER32_MessageBoxTimeoutW_4AD210
004AD214 Hi_fp_USER32_KillTimer_4AD214
004AD218 Hi_fp_USER32_SetFocus_4AD218
004AD21C Hi_fp_USER32_GetWindow_4AD21C
004AD220 Hi_fp_USER32_GetWindowLongW_4AD220
004AD224 Hi_fp_USER32_GetMonitorInfoW_4AD224
004AD228 Hi_fp_USER32_GetWindowRect_4AD228
004AD22C Hi_fp_USER32_GetParent_4AD22C
004AD230 Hi_fp_USER32_GetClientRect_4AD230
004AD234 Hi_fp_USER32_MapWindowPoints_4AD234
004AD238 Hi_fp_USER32_SetWindowPos_4AD238
004AD23C Hi_fp_USER32_GetSystemMetrics_4AD23C
004AD240 Hi_fp_USER32_LoadImageW_4AD240
004AD244 Hi_fp_USER32_EnableWindow_4AD244
004AD248 Hi_fp_USER32_SendMessageW_4AD248
004AD24C Hi_fp_USER32_SetWindowTextW_4AD24C
004AD250 Hi_fp_USER32_IsDialogMessageW_4AD250
004AD254 Hi_fp_USER32_GetDlgItem_4AD254
004AD258 Hi_fp_USER32_PostQuitMessage_4AD258
004AD25C Hi_fp_USER32_PostMessageW_4AD25C
004AD260 Hi_fp_USER32_SetTimer_4AD260
004AD264 Hi_fp_USER32_GetWindowTextA_4AD264
004AD268 Hi_fp_USER32_GetWindowTextW_4AD268
004AD26C Hi_fp_USER32_SetWindowLongW_4AD26C
004AD270 Hi_fp_USER32_CreateDialogParamW_4AD270
004AD274 Hi_fp_USER32_UnregisterClassW_4AD274
004AD278 Hi_fp_USER32_DestroyWindow_4AD278
004AD27C Hi_fp_USER32_SetWinEventHook_4AD27C
004AD280 Hi_fp_USER32_DefWindowProcW_4AD280
004AD284 Hi_fp_USER32_PeekMessageW_4AD284
004AD288 Hi_fp_USER32_GetMessageW_4AD288
004AD28C Hi_fp_USER32_TranslateMessage_4AD28C
004AD290 Hi_fp_USER32_DispatchMessageW_4AD290
004AD294 Hi_fp_USER32_ShowWindow_4AD294
004AD298 Hi_fp_USER32_CharNextW_4AD298
004AD29C Hi_fp_USER32_GetWindowLongA_4AD29C
004AD2A0 Hi_fp_USER32_MonitorFromWindow_4AD2A0
004AD2A8 Hi_fp_WINMM_waveOutGetPosition_4AD2A8
004AD2AC Hi_fp_WINMM_waveOutOpen_4AD2AC
004AD2B0 Hi_fp_WINMM_waveOutPrepareHeader_4AD2B0
004AD2B4 Hi_fp_WINMM_waveOutReset_4AD2B4
004AD2B8 Hi_fp_WINMM_waveOutUnprepareHeader_4AD2B8
004AD2BC Hi_fp_WINMM_waveOutWrite_4AD2BC
004AD2C0 Hi_fp_WINMM_waveOutClose_4AD2C0
004AD2C8 Hi_fp_ole32_CoTaskMemRealloc_4AD2C8
004AD2CC Hi_fp_ole32_CoTaskMemAlloc_4AD2CC
004AD2D0 Hi_fp_ole32_CoCreateInstance_4AD2D0
004AD2D4 Hi_fp_ole32_CoInitialize_4AD2D4
004AD2D8 Hi_fp_ole32_CoUninitialize_4AD2D8
004AD2DC Hi_fp_ole32_CoTaskMemFree_4AD2DC
004B3044 Hi_self_cookie
004B37B4 Hi_dllnameArraySize
004B37BC Hi_StartEntryRVA
004B37C0 Hi_VA2
004B37C4 Hi_decxorFourTor
004B37C8 Hi_CntB1h_of_VAM_2C4h_as_dwArray
004B37CC Hi_VA3_for_bwns_SEG
004B37D0 Hi_decxorFourTor_forFuncName
004B37D4 Hi_OFFSET_VA2_to_bwns
004B37D8 Hi_RVA1_for_idata
004B37DC Hi_RVA4
004B37E0 Hi_RVA1_size
004B37E4 Hi_RVA2
004B8690 Hi_Init_for_Hi_VAM1_2C4h_asFuncTable
004B8A20 Hi_Init_kernel_functionPtrs
004B8B00 Hi_get_fp_of_GetProcAddress
004B8BC0 Hi_self_cookie_check
004C38CC Hi_ExitProcess
004C38D0 Hi_VirtualAlloc
004C38D4 Hi_VirtualProtect
004C38D8 Hi_GetModuleHandleA
004C38DC Hi_LoadLibraryA
004C38E0 Hi_GetProcAddress
004C38E4 Hi_VAM1_2C4h_asFuncTable
004C38E8 Hi_initD
004C38EC Hi_init3
004C38F0 Hi_Init7
004C38F4 Hi_curModuleHandle
004C38F8 Hi_StartEntryVA
004B84F3 call Hi_Init_kernel_functionPtrs
函数的调用完成基本核心函数指针的获取工作
.bwns:004B8A4C mov esi, [ebp+loc_hKernel32]
.bwns:004B8A4F call Hi_get_fp_of_GetProcAddress
.bwns:004B8A54 push offset aLoadlibrarya ; "LoadLibraryA"
.bwns:004B8A59 push esi
.bwns:004B8A5A mov ds:Hi_GetProcAddress, eax
.bwns:004B8A5F call eax
.bwns:004B8A61 push offset aGetmodulehandl ; "GetModuleHandleA"
.bwns:004B8A66 push esi
.bwns:004B8A67 mov ds:Hi_LoadLibraryA, eax
.bwns:004B8A6C call ds:Hi_GetProcAddress
.bwns:004B8A72 push offset aVirtualprotect ; "VirtualProtect"
.bwns:004B8A77 push esi
.bwns:004B8A78 mov ds:Hi_GetModuleHandleA, eax
.bwns:004B8A7D call ds:Hi_GetProcAddress
.bwns:004B8A83 push offset aExitprocess ; "ExitProcess"
.bwns:004B8A88 push esi
.bwns:004B8A89 mov ds:Hi_VirtualProtect, eax
.bwns:004B8A8E call ds:Hi_GetProcAddress
.bwns:004B8A94 push offset aVirtualalloc ; "VirtualAlloc"
.bwns:004B8A99 push esi
.bwns:004B8A9A mov ds:Hi_ExitProcess, eax
.bwns:004B8A9F call ds:Hi_GetProcAddress
.bwns:004B8AA5 push 0
.bwns:004B8AA7 mov ds:Hi_VirtualAlloc, eax
.bwns:004B8AAC call ds:Hi_GetModuleHandleA
.bwns:004B8AB2 mov ds:Hi_curModuleHandle, eax
.bwns:004B8AB7 mov eax, ds:Hi_CntB1h_of_VAM_2C4h_as_dwArray
.bwns:004B8ABC push 40h
.bwns:004B8ABE push 3000h
.bwns:004B8AC3 shl eax, 2
.bwns:004B8AC6 push eax
.bwns:004B8AC7 push 0
.bwns:004B8AC9 call ds:Hi_VirtualAlloc
.bwns:004B8ACF pop edi
.bwns:004B8AD0 mov ds:Hi_VAM1_2C4h_asFuncTable, eax
.bwns:004B8AD5 mov ds:Hi_Init7, 7
.bwns:004B8ADF mov ds:Hi_init3, 3
.bwns:004B8AE9 mov ds:Hi_initD, 0Dh
Hi_CntB1h_of_VAM_2C4h_as_dwArray 是导入表被隐藏保护的函数个数
004B8537 call Hi_Init_for_Hi_VAM1_2C4h_asFuncTable
调用完成导入表机制的重构,使用了二级跳板机制,机制内部对函数指针做了加密,
也就导致了直接使用ImportREC是没法完成IAT修复。
al = 0
rb = c_ubyte(0)
xorFourTor = [0x16, 0x0A9, 0xD8, 0x2E]
for i in xrange(0,0x5D):
rb.value = GetOriginalByte(0x4b2aa5+i)
if rb.value == 0:
al = 0
PatchByte(0x4b2aa5+i,rb.value)
else:
rb.value = (rb.value>>2)|(rb.value<<6)
rb.value = rb.value ^ xorFourTor[al&3]
al += 1
rb.value = rb.value ^ al
PatchByte(0x4b2aa5+i,rb.value)
通过上述IDAPython脚本,我们可以得到加密的dll模块名称列表
这里我们是静态分析,动态调试需在在敏感点下断,
否则得不到这些解密的内容,因为完成IAT二级跳机制后,这些模块名称,
也包括后面的函数名称都会被擦除。
.bwns:004B2AA5 aWinmmDll db 'WINMM.dll',0
.bwns:004B2AAF aKernel32Dll_0 db 'KERNEL32.dll',0
.bwns:004B2ABC aUser32Dll db 'USER32.dll',0
.bwns:004B2AC7 aAdvapi32Dll_0 db 'ADVAPI32.dll',0
.bwns:004B2AD4 aOle32Dll db 'ole32.dll',0
.bwns:004B2ADE aOleaut32Dll db 'OLEAUT32.dll',0
.bwns:004B2AEB aComctl32Dll db 'COMCTL32.dll',0
.bwns:004B2AF8 aPsapiDll db 'PSAPI.DLL',0
在 H_VA4 ; 4c6000处,是每个导入函数的描述信息块
每个信息块大小为0x10,共0xB1个导入函数
函数信息块用来加载函数的基本逻辑如下
if FuncInfoBlock.00hb & 1 == 0:
if 0 == hM=GetModuleHandleA(0x4b2aa5+FuncInfoBlock.04hww):
hM=LoadLibraryA(0x4b2aa5+FuncInfoBlock.04hww)
lpszfn = 0x004B2000+FuncInfoBlock.0Chww
xordecfn(lpszfn)
fp = GetProcAddress(hM,lpszfn)
memset(lpszfn,0,len of lpszfn)
else:
if 0 == hM=GetModuleHandleA(0x4b2aa5+FuncInfoBlock.04hww):
hM=LoadLibraryA(0x4b2aa5+FuncInfoBlock.04hww)
fp = GetProcAddress(hM,FuncInfoBlock.00hww >> 1)
FuncInfoBlock{
+00h 若低位为1,则高31位为导入函数的函数索引号
+04h 这个是指向函数所属模块的名称偏移,相对前面的模块列表首地址 004B2AA5 而言
+08h 这个是原IAT函数地址,未加壳时,此指向地址存放导入函数地址
+0Ch 指向以函数名称导入的(+.00hb低位为1时)函数名称在0x004B2000处的偏移
}
def xordecfn(ea):
Hi_decxorFourTor_forFuncName=[0xcd,0x9b,0xc7,0xe4]
al = 0
rb = c_ubyte(0)
while True:
rb.value = GetOriginalByte(ea)
if rb.value == 0:
break
else:
rb.value = (rb.value>>3)|(rb.value<<5)
rb.value = rb.value ^ Hi_decxorFourTor_forFuncName[al&3]
al += 1
rb.value = rb.value ^ al
PatchByte(ea,rb.value)
ea+=1
for i in xrange(0,0xb1):
edi = i*0x10
FuncInfoBlock = 0x4c6000 + edi
mn = GetString(0x4b2aa5+Dword(FuncInfoBlock+0x04),-1,ASCSTR_C)
fn = Dword(FuncInfoBlock)
if (fn&1) != 0:
fn = fn >> 1
print ' 0x{:02X}:"{}[{}]",'.format(i,mn[:-4],fn)
else:
lpszfn = 0x004B2000+Dword(FuncInfoBlock+0x0C)
#print "{}: {:X}".format(mn,lpszfn)
xordecfn(lpszfn)
fn = GetString(lpszfn,-1,ASCSTR_C)
print ' 0x{:02X}:"{}.{}",'.format(i,mn[:-4],fn)
#da_bytes.create_strlit(lpszfn,fn.__len__()+1,0)
通过上述IDAPython脚本我们得以解密得到加壳前原地址表对应的模块函数列表
其中我们对两个函数索引导入的更改为相应名称的形式
这个可以直接用MS编译器工具查询,如
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)