话说这个东西是前天拿到的,但是当时在家,东西也不全。平直接感觉是加壳了。去peid官方下载了个没有更新特征库的报了个什么都没发现,晕死。
今天重新查壳发现是Armadillo V6.X Minimum Protection -> Silicon Realms Toolworks * Sign.By.fly * 20081227 *,脱壳后发现程序是用bc++写的:
这个文章网上有的,这里只是做个类似笔记的东西,没别的用处(文章本身就是依样画葫芦。)。
1.用od载入程序后,od停在
00660AC2 > $ E8 833C0000 call 0066474A
00660AC7 .^ E9 16FEFFFF jmp 006608E2
00660ACC /$ 6A 0C push 0C
00660ACE |. 68 18436800 push 00684318
00660AD3 |. E8 641E0000 call 0066293C
00660AD8 |. 8365 E4 00 and dword ptr [ebp-1C], 0
00660ADC |. 8B75 08 mov esi, dword ptr [ebp+8]
00660ADF |. 3B35 70746800 cmp esi, dword ptr [687470]
00660AE5 |. 77 22 ja short 00660B09
00660AE7 |. 6A 04 push 4
00660AE9 |. E8 C31A0000 call 006625B1
00660AEE |. 59 pop ecx
00660AEF |. 8365 FC 00 and dword ptr [ebp-4], 0
00660AF3 |. 56 push esi
00660AF4 |. E8 01450000 call 00664FFA
00660AF9 |. 59 pop ecx
00660AFA |. 8945 E4 mov dword ptr [ebp-1C], eax
00660AFD |. C745 FC FEFFF>mov dword ptr [ebp-4], -2
00660B04 |. E8 09000000 call 00660B12
00660B09 |> 8B45 E4 mov eax, dword ptr [ebp-1C]
00660B0C |. E8 701E0000 call 00662981
00660B11 \. C3 retn
然后利用插件hideod,否则后面的步骤没法执行,会直接弹出检测到调试器的错误提示。下第一个断点BP VirtualProtect,处理IAT加密,下好断点后Shift+F9,注意把握返回时机(缓冲比较大的)。
然后直接alt+F9返回,会跳转到类似下面的代码处:1
00F4D0CC 8B8D C8D5FFFF mov ecx, dword ptr [ebp-2A38]
00F4D0D2 51 push ecx
00F4D0D3 8B95 C4D5FFFF mov edx, dword ptr [ebp-2A3C]
00F4D0D9 52 push edx
00F4D0DA 8B85 74D8FFFF mov eax, dword ptr [ebp-278C]
00F4D0E0 0385 C0D5FFFF add eax, dword ptr [ebp-2A40]
00F4D0E6 50 push eax
00F4D0E7 E8 24EA0000 call 00F5BB10
00F4D0EC 83C4 0C add esp, 0C
00F4D0EF 8D8D D4D5FFFF lea ecx, dword ptr [ebp-2A2C]
00F4D0F5 51 push ecx
00F4D0F6 8B95 D4D5FFFF mov edx, dword ptr [ebp-2A2C]
00F4D0FC 52 push edx
00F4D0FD 8B85 C8D5FFFF mov eax, dword ptr [ebp-2A38]
00F4D103 50 push eax
00F4D104 8B8D 74D8FFFF mov ecx, dword ptr [ebp-278C]
00F4D10A 038D C0D5FFFF add ecx, dword ptr [ebp-2A40]
00F4D110 51 push ecx
00F4D111 FF15 2C31F700 call dword ptr [F7312C] ; kernel32.VirtualProtect
在此处搜索命令:push 100,选择整个区段。找到后网上查找push ebp,上面会有甚多的int3中断。类似下面的结构:11
00F0327B CC int3
00F0327C CC int3
00F0327D CC int3
00F0327E CC int3
00F0327F CC int3
00F03280 55 push ebp
00F03281 8BEC mov ebp, esp
00F03283 83EC 2C sub esp, 2C
00F03286 833D 20F6F700 0>cmp dword ptr [F7F620], 0
00F0328D 75 59 jnz short 00F032E8
00F0328F C745 EC D125ACB>mov dword ptr [ebp-14], BFAC25D1
00F03296 68 00010000 push 100
00F0329B E8 F6850500 call 00F5B896
修改push ebp为retn,直接返回,然后删除第一个断点。到此第一步结束。
2.下第二个断点BP CreateThread 查找程序OEP Shift+F9一次后会停在下面的代码处:1
7C8106C7 > 8BFF mov edi, edi
7C8106C9 55 push ebp
7C8106CA 8BEC mov ebp, esp
7C8106CC FF75 1C push dword ptr [ebp+1C]
7C8106CF FF75 18 push dword ptr [ebp+18]
7C8106D2 FF75 14 push dword ptr [ebp+14]
7C8106D5 FF75 10 push dword ptr [ebp+10]
7C8106D8 FF75 0C push dword ptr [ebp+C]
7C8106DB FF75 08 push dword ptr [ebp+8]
7C8106DE 6A FF push -1
7C8106E0 E8 D7FDFFFF call CreateRemoteThread
7C8106E5 5D pop ebp
7C8106E6 C2 1800 retn 18
然后F8单步,直到执行到如下代码处:
00F3658C 50 push eax
00F3658D FF15 9032F700 call dword ptr [F73290] ; kernel32.CloseHandle
00F36593 5E pop esi
00F36594 5B pop ebx
00F36595 8BE5 mov esp, ebp
00F36597 5D pop ebp
00F36598 C3 retn
有的文章说alt+f9直接执行到返回,但是我执行时没有效果,所以直接F8单步也可。这里注意观察代码窗口,如果正常的话会出现红色的字体一闪而过,也就是代码正确解压了,否则就是出错了,重复
上面的步骤即可。
然后一直F8在这个调用返回后会执行到如下代码处:
00F53414 83C4 04 add esp, 4
00F53417 B9 E004F800 mov ecx, 0F804E0
00F5341C E8 4F8EFBFF call 00F0C270
00F53421 0FB6C0 movzx eax, al
00F53424 85C0 test eax, eax
00F53426 74 0C je short 00F53434
00F53428 6A 01 push 1
00F5342A B9 E004F800 mov ecx, 0F804E0
00F5342F E8 7C7BFCFF call 00F1AFB0
00F53434 C705 40C7F700 B>mov dword ptr [F7C740], 0F76EBC
00F5343E B9 24F6F700 mov ecx, 0F7F624
00F53443 E8 E8FFFAFF call 00F03430
00F53448 C745 F0 0000000>mov dword ptr [ebp-10], 0
00F5344F 8D4D E8 lea ecx, dword ptr [ebp-18]
00F53452 51 push ecx
00F53453 68 4035F500 push 0F53540
00F53458 FF15 9801F800 call dword ptr [F80198]
00F5345E 83C4 08 add esp, 8
00F53461 8B15 440BF800 mov edx, dword ptr [F80B44] ; NB_SMS.00400000
00F53467 8955 E4 mov dword ptr [ebp-1C], edx
00F5346A B8 1F000000 mov eax, 1F
00F5346F C1E0 02 shl eax, 2
00F53472 8B0D 2C0BF800 mov ecx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F53478 8B15 2C0BF800 mov edx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F5347E 8B35 2C0BF800 mov esi, dword ptr [F80B2C] ; NB_SMS.0067D398
00F53484 8BB6 88000000 mov esi, dword ptr [esi+88]
00F5348A 3372 14 xor esi, dword ptr [edx+14]
00F5348D 333401 xor esi, dword ptr [ecx+eax]
00F53490 0375 E4 add esi, dword ptr [ebp-1C]
00F53493 8975 F4 mov dword ptr [ebp-C], esi
00F53496 8B45 08 mov eax, dword ptr [ebp+8]
00F53499 8338 00 cmp dword ptr [eax], 0
00F5349C 75 43 jnz short 00F534E1
00F5349E 8B0D 2C0BF800 mov ecx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F534A4 8B15 2C0BF800 mov edx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F534AA 8B81 80000000 mov eax, dword ptr [ecx+80]
00F534B0 3342 14 xor eax, dword ptr [edx+14]
00F534B3 8B0D 2C0BF800 mov ecx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F534B9 3341 40 xor eax, dword ptr [ecx+40]
00F534BC 8945 E0 mov dword ptr [ebp-20], eax
00F534BF 8B55 08 mov edx, dword ptr [ebp+8]
00F534C2 8B42 18 mov eax, dword ptr [edx+18]
00F534C5 50 push eax
00F534C6 8B4D 08 mov ecx, dword ptr [ebp+8]
00F534C9 8B51 14 mov edx, dword ptr [ecx+14]
00F534CC 52 push edx
00F534CD 8B45 08 mov eax, dword ptr [ebp+8]
00F534D0 8B48 10 mov ecx, dword ptr [eax+10]
00F534D3 51 push ecx
00F534D4 8B55 F4 mov edx, dword ptr [ebp-C]
00F534D7 2B55 E0 sub edx, dword ptr [ebp-20]
00F534DA FFD2 call edx
00F534DC 8945 FC mov dword ptr [ebp-4], eax
00F534DF EB 4B jmp short 00F5352C
00F534E1 8B45 08 mov eax, dword ptr [ebp+8]
00F534E4 8338 01 cmp dword ptr [eax], 1
00F534E7 75 43 jnz short 00F5352C
00F534E9 8B0D 2C0BF800 mov ecx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F534EF 8B15 2C0BF800 mov edx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F534F5 8B81 80000000 mov eax, dword ptr [ecx+80]
00F534FB 3342 14 xor eax, dword ptr [edx+14]
00F534FE 8B0D 2C0BF800 mov ecx, dword ptr [F80B2C] ; NB_SMS.0067D398
00F53504 3341 40 xor eax, dword ptr [ecx+40]
00F53507 8945 DC mov dword ptr [ebp-24], eax
00F5350A 8B55 08 mov edx, dword ptr [ebp+8]
00F5350D 8B42 04 mov eax, dword ptr [edx+4]
00F53510 50 push eax
00F53511 8B4D 08 mov ecx, dword ptr [ebp+8]
00F53514 8B51 08 mov edx, dword ptr [ecx+8]
00F53517 52 push edx
00F53518 6A 00 push 0
00F5351A 8B45 08 mov eax, dword ptr [ebp+8]
00F5351D 8B48 0C mov ecx, dword ptr [eax+C]
00F53520 51 push ecx
00F53521 8B55 F4 mov edx, dword ptr [ebp-C]
00F53524 2B55 DC sub edx, dword ptr [ebp-24]
00F53527 FFD2 call edx ; 这里就是程序的入口点,直接F7跟入就到了程序的入口点了
00F53529 8945 FC mov dword ptr [ebp-4], eax
00F5352C 8B45 FC mov eax, dword ptr [ebp-4]
00F5352F 5E pop esi
00F53530 8BE5 mov esp, ebp
00F53532 5D pop ebp
00F53533 C3 retn
00F53534 CC int3
然后一直F8知道执行的注释中所说的入口点,然后跟入即可:
00401480 /EB 10 jmp short 00401492
00401482 |66:623A bound di, dword ptr [edx]
00401485 |43 inc ebx
00401486 |2B2B sub ebp, dword ptr [ebx]
00401488 |48 dec eax
00401489 |4F dec edi
0040148A |4F dec edi
0040148B |4B dec ebx
0040148C |90 nop
0040148D -|E9 98F05100 jmp 0092052A
00401492 \A1 8BF05100 mov eax, dword ptr [51F08B]
00401497 C1E0 02 shl eax, 2
0040149A A3 8FF05100 mov dword ptr [51F08F], eax
0040149F 52 push edx
004014A0 6A 00 push 0
004014A2 E8 CFCF1100 call 0051E476 ; jmp 到 kernel32.GetModuleHandleA
004014A7 8BD0 mov edx, eax
004014A9 E8 129C0F00 call 004FB0C0
004014AE 5A pop edx
004014AF E8 709B0F00 call 004FB024
到此最主要的工作就完成了,剩下的就是修复了。
3.这里需要说明的是,修复输入表的时候由于输入表不连续直接修复会有很多指针无效:
0051E368 - FF25 20115600 jmp dword ptr [561120] ; ADVAPI32.GetUserNameA
0051E36E - FF25 24115600 jmp dword ptr [561124] ; ADVAPI32.RegCloseKey
0051E374 - FF25 28115600 jmp dword ptr [561128] ; ADVAPI32.RegCreateKeyExA
0051E37A - FF25 2C115600 jmp dword ptr [56112C] ; ADVAPI32.RegOpenKeyExA
0051E380 - FF25 30115600 jmp dword ptr [561130] ; ADVAPI32.RegQueryValueExA
0051E386 - FF25 34115600 jmp dword ptr [561134] ; ADVAPI32.RegSetValueExA
0051E38C - FF25 14135600 jmp dword ptr [561314] ; kernel32.Beep
0051E392 - FF25 18135600 jmp dword ptr [561318] ; kernel32.CloseHandle
0051E398 - FF25 1C135600 jmp dword ptr [56131C] ; kernel32.CompareStringA
0051E39E - FF25 20135600 jmp dword ptr [561320] ; kernel32.CreateDirectoryA
0051E3A4 - FF25 24135600 jmp dword ptr [561324] ; kernel32.CreateEventA
0051E3AA - FF25 28135600 jmp dword ptr [561328] ; kernel32.CreateFileA
0051E3B0 - FF25 2C135600 jmp dword ptr [56132C] ; kernel32.CreateThread
0051E3B6 - FF25 30135600 jmp dword ptr [561330] ; kernel32.DebugBreak
0051E3BC - FF25 34135600 jmp dword ptr [561334] ; ntdll.RtlDeleteCriticalSection
0051E3C2 - FF25 38135600 jmp dword ptr [561338] ; kernel32.DeleteFileA
0051E3C8 - FF25 3C135600 jmp dword ptr [56133C] ; ntdll.RtlEnterCriticalSection
0051E3CE - FF25 40135600 jmp dword ptr [561340] ; kernel32.EnumCalendarInfoA
0051E3D4 - FF25 44135600 jmp dword ptr [561344] ; kernel32.ExitProcess
0051E3DA - FF25 48135600 jmp dword ptr [561348] ; kernel32.FileTimeToDosDateTime
0051E3E0 - FF25 4C135600 jmp dword ptr [56134C] ; kernel32.FileTimeToLocalFileTime
0051E3E6 - FF25 50135600 jmp dword ptr [561350] ; kernel32.FindClose
0051E3EC - FF25 54135600 jmp dword ptr [561354] ; kernel32.FindFirstFileA
0051E3F2 - FF25 58135600 jmp dword ptr [561358] ; kernel32.FindNextFileA
0051E3F8 - FF25 5C135600 jmp dword ptr [56135C] ; kernel32.FindResourceA
0051E3FE - FF25 60135600 jmp dword ptr [561360] ; kernel32.FormatMessageA
0051E404 - FF25 64135600 jmp dword ptr [561364] ; kernel32.FreeLibrary
0051E40A - FF25 68135600 jmp dword ptr [561368] ; kernel32.FreeResource
0051E410 - FF25 6C135600 jmp dword ptr [56136C] ; kernel32.GetACP
0051E416 - FF25 70135600 jmp dword ptr [561370] ; kernel32.GetCPInfo
0051E41C - FF25 74135600 jmp dword ptr [561374] ; kernel32.GetCommandLineA
0051E422 - FF25 78135600 jmp dword ptr [561378] ; kernel32.GetComputerNameA
0051E428 - FF25 7C135600 jmp dword ptr [56137C] ; kernel32.GetCurrentProcessId
0051E42E - FF25 80135600 jmp dword ptr [561380] ; kernel32.GetCurrentThreadId
0051E434 - FF25 84135600 jmp dword ptr [561384] ; kernel32.GetDateFormatA
0051E43A - FF25 88135600 jmp dword ptr [561388] ; kernel32.GetDiskFreeSpaceA
0051E440 - FF25 8C135600 jmp dword ptr [56138C] ; kernel32.GetEnvironmentStringsA
0051E446 - FF25 90135600 jmp dword ptr [561390] ; kernel32.GetEnvironmentVariableA
0051E44C - FF25 94135600 jmp dword ptr [561394] ; kernel32.GetFileAttributesA
0051E452 - FF25 98135600 jmp dword ptr [561398] ; kernel32.GetFileSize
0051E458 - FF25 9C135600 jmp dword ptr [56139C] ; kernel32.GetFileType
0051E45E - FF25 A0135600 jmp dword ptr [5613A0] ; ntdll.RtlGetLastWin32Error
0051E464 - FF25 A4135600 jmp dword ptr [5613A4] ; kernel32.GetLocalTime
0051E46A - FF25 A8135600 jmp dword ptr [5613A8] ; kernel32.GetLocaleInfoA
0051E470 - FF25 AC135600 jmp dword ptr [5613AC] ; kernel32.GetModuleFileNameA
0051E476 - FF25 B0135600 jmp dword ptr [5613B0] ; kernel32.GetModuleHandleA
0051E47C - FF25 B4135600 jmp dword ptr [5613B4] ; kernel32.GetOEMCP
0051E482 - FF25 B8135600 jmp dword ptr [5613B8] ; kernel32.GetPrivateProfileStringA
0051E488 - FF25 BC135600 jmp dword ptr [5613BC] ; kernel32.GetProcAddress
0051E48E - FF25 C0135600 jmp dword ptr [5613C0] ; kernel32.GetProcessHeap
0051E494 - FF25 C4135600 jmp dword ptr [5613C4] ; kernel32.GetProfileStringA
0051E49A - FF25 C8135600 jmp dword ptr [5613C8] ; kernel32.GetStartupInfoA
0051E4A0 - FF25 CC135600 jmp dword ptr [5613CC] ; kernel32.GetStdHandle
0051E4A6 - FF25 D0135600 jmp dword ptr [5613D0] ; kernel32.GetStringTypeA
0051E4AC - FF25 D4135600 jmp dword ptr [5613D4] ; kernel32.GetStringTypeExA
0051E4B2 - FF25 D8135600 jmp dword ptr [5613D8] ; kernel32.GetStringTypeW
0051E4B8 - FF25 DC135600 jmp dword ptr [5613DC] ; kernel32.GetSystemDefaultLangID
0051E4BE - FF25 E0135600 jmp dword ptr [5613E0] ; kernel32.GetSystemInfo
0051E4C4 - FF25 E4135600 jmp dword ptr [5613E4] ; kernel32.GetThreadLocale
0051E4CA - FF25 E8135600 jmp dword ptr [5613E8] ; kernel32.GetTickCount
0051E4D0 - FF25 EC135600 jmp dword ptr [5613EC] ; kernel32.GetTimeZoneInformation
这里可以发现第一个dll的输入表距离第二个dll的输入表较远,直接修复得到的指针都是无效的,这里需要先修复第一个,然后再修复后面的即可:
第一次按照iat自动搜索的结结果修复即可,长度填100,目标是先修复第一个dll的输入表:
第二次填出第二个dll的起始位置:161314长度填1000直接搜索删除无效指针,修复dump后的文件即可.