看雪的 原文在如下地址
http://bbs.pediy.com/showthread.php?t=61334
在操作到 13.5.4 构造重定位表 时我遇到了麻烦,
因为手里正在处理的被asprotec加密的DLL文件重定位项很多,超出了hideOD默认的申请空间大小(3000H)。
于是想到利用外壳里面包含的申请内存的函数代码来实现。
经查找在本区段的前面代码有
00A02339 6A 04 push 4
00A0233B 68 00100000 push 1000
00A02340 50 push eax ; 注释此处为申请空间的大小
00A02341 6A 00 push 0
00A02343 FF95 79294400 call dword ptr [ebp+442979] ;注释此处函数正是kernel32.VirtualAlloc
所以我们既可以保存好现场后跳过来这里执行后再返回,也可以自己重写一遍代码。
我这里给出一个重写代码的方法。
以下为原程序里重定位实现代码所在地
0A023F9 /74 08 je short 00A02403
00A023FB |8B03 mov eax, dword ptr [ebx]
00A023FD |8785 592A4400 xchg dword ptr [ebp+442A59], eax
00A02403 \8B95 D8304400 mov edx, dword ptr [ebp+4430D8] ; 新堆地址
00A02409 8B85 512A4400 mov eax, dword ptr [ebp+442A51] ; 默认基址40000
00A0240F 2BD0 sub edx, eax ; 判断是否需要重定位
00A02411 74 75 je short 00A02488
00A02413 8BC2 mov eax, edx
00A02415 C1E8 10 shr eax, 10
00A02418 33DB xor ebx, ebx ; EBX = 0
00A0241A 8BB5 5D2A4400 mov esi, dword ptr [ebp+442A5D] ; 4F000
00A02420 03B5 D8304400 add esi, dword ptr [ebp+4430D8]
00A02426 833E 00 cmp dword ptr [esi], 0 ; 外部循环,判断是否结束
00A02429 74 5D je short 00A02488
00A0242B 8B4E 04 mov ecx, dword ptr [esi+4]
00A0242E 83E9 08 sub ecx, 8
00A02431 D1E9 shr ecx, 1
00A02433 8B3E mov edi, dword ptr [esi]
00A02435 03BD D8304400 add edi, dword ptr [ebp+4430D8]
00A0243B 83C6 08 add esi, 8
00A0243E 66:8B1E mov bx, word ptr [esi] ; 内部循环到这里
00A02441 C1EB 0C shr ebx, 0C
00A02444 83FB 01 cmp ebx, 1
00A02447 74 0C je short 00A02455
00A02449 83FB 02 cmp ebx, 2
00A0244C 74 16 je short 00A02464
00A0244E 83FB 03 cmp ebx, 3
00A02451 74 20 je short 00A02473
00A02453 EB 2C jmp short 00A02481
00A02455 66:8B1E mov bx, word ptr [esi]
00A02458 81E3 FF0F0000 and ebx, 0FFF
00A0245E 66:01041F add word ptr [edi+ebx], ax
00A02462 EB 1D jmp short 00A02481
00A02464 66:8B1E mov bx, word ptr [esi]
00A02467 81E3 FF0F0000 and ebx, 0FFF
00A0246D 66:01141F add word ptr [edi+ebx], dx
00A02471 EB 0E jmp short 00A02481
00A02473 66:8B1E mov bx, word ptr [esi]
00A02476 81E3 FF0F0000 and ebx, 0FFF
00A0247C 01141F add dword ptr [edi+ebx], edx ; 重定位语句
00A0247F EB 20 jmp short 00A02481
00A02481 83C6 02 add esi, 2
00A02484 ^ E2 B8 loopd short 00A0243E
00A02486 ^ EB 9E jmp short 00A02426
00A02488 8BB5 612A4400 mov esi, dword ptr [ebp+442A61]
00A0248E 8B95 D8304400 mov edx, dword ptr [ebp+4430D8]
00A02494 03F2 add esi, edx
00A02496 8B46 0C mov eax, dword ptr [esi+C]
00A02499 85C0 test eax, eax
00A0249B 0F84 0A010000 je 00A025AB
按照看雪的指示,我们打补丁在 重定位实现语句后面。
跳转后在新申请的空间里面保存重定位数据。
本区段空间的起始地址为9B0000,在执行到此处是上面为一大段0000,所以我们也可以利用此处来代替看雪文章里提到的新区段起始处的dword 作为 目的地址指针。
我所修改添加的代码如下,给各位做个参考:
00A0247C 01141F add dword ptr [edi+ebx], edx ; 重定位语句
00A0247F EB 20 jmp short 00A024A1
00A024A1 60 pushad
00A024A2 A1 00009B00 mov eax, dword ptr [9B0000]
00A024A7 85C0 test eax, eax
00A024A9 74 1A je short 00A024C5
00A024AB A1 00009B00 mov eax, dword ptr [9B0000]
00A024B0 8D143B lea edx, dword ptr [ebx+edi]
00A024B3 81EA 00009B00 sub edx, 9B0000
00A024B9 8910 mov dword ptr [eax], edx
00A024BB 8305 00009B00 0>add dword ptr [9B0000], 4
00A024C2 61 popad
00A024C3 ^ EB BC jmp short 00A02481
00A024C5 6A 04 push 4
00A024C7 68 00100000 push 1000
00A024CC 68 00500400 push 45000 ; 注释此处为申请空间的大小,记住此处空间一定要设置大小为 足够用
00A024D1 6A 00 push 0
00A024D3 FF95 79294400 call dword ptr [ebp+442979] ;注释:此处为kernel32.VirtualAlloc
00A024D9 A3 00009B00 mov dword ptr [9B0000], eax
00A024DE ^ EB C2 jmp short 00A024A2
补丁写好之后,在00A02488 8BB5 612A4400 mov esi, dword ptr [ebp+442A61]
处下断点,运行,断下后可以由9B0000处重定位数据的地址指针找到并存储好宝贝的重定位数据了。
呵呵。。
一直都在潜水,初次发表,请各位大小虾多多指正。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)