首先参考看雪文章
http://bbs.pediy.com/showthread.php?t=13146
工具olldbg,ida 6.3,ImpREC 1.7c ,lordPE
1 ) olldbg载入目标程序
Bp CreateFileA 执行后取消断点,返回并修改
0088BD93 E8 1A000000 CALL PPOS.0088BDB2
0088BD98 83C4 10 ADD ESP,10 前面文章中说的断点处,可以算出偏移直接断于此处(为啥可以直接算出偏移?因为彩虹狗会对齐代码数据,比如原文断点为00455D98,0088BD98- 00455D98 = 436000,由此可见,以后的断点只要加上偏移即可)
0088BD9B 85C0 TEST EAX,EAX
0088BD9D 75 0C JNZ SHORT PPOS.0088BDAB
0088BD9F C705 842C8B00 0>MOV DWORD PTR DS:[8B2C84],1
0088BDA9 ^ EB A0 JMP SHORT PPOS.0088BD4B
0088BDAB 8BC3 MOV EAX,EBX
0088BDAD 5F POP EDI
0088BDAE 5E POP ESI
0088BDAF 5B POP EBX
0088BDB0 C9 LEAVE
0088BDB1 C3 RETN
0088BDB2 33C0 XOR EAX,EAX 读狗CALL的入口代码,已经改成
0088BDB4 C3 RETN
0088BDB5 81EC 10010000 SUB ESP,110
2)按原文算key的偏移 451DC1+436000 = 887DC1 直接在此下断点
00887DBD 0000 ADD BYTE PTR DS:[EAX],AL
00887DBF 1000 ADC BYTE PTR DS:[EAX],AL
00887DC1 0F84 84000000 JE PPOS.00887E4B 修改Z FLAG直接跳
00887DC7 A1 38208B00 MOV EAX,DWORD PTR DS:[8B2038]
00887DCC 48 DEC EAX
00887DCD 8BC8 MOV ECX,EAX
00887DCF 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4]
00887DD2 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4]
00887DD5 8D0441 LEA EAX,DWORD PTR DS:[ECX+EAX*2]
00887DD8 8D0445 10108B00 LEA EAX,DWORD PTR DS:[EAX*2+8B1010]
00887DDF 05 14060000 ADD EAX,614
3)再次断于下面红色字体处
00887E50 3305 8C108B00 XOR EAX,DWORD PTR DS:[8B108C]
00887E56 A3 4C308B00 MOV DWORD PTR DS:[8B304C],EAX
00887E5B A1 4C308B00 MOV EAX,DWORD PTR DS:[8B304C]
00887E60 A3 C6128B00 MOV DWORD PTR DS:[8B12C6],EAX
00887E65 8D85 84FEFFFF LEA EAX,DWORD PTR SS:[EBP-17C]
00887E6B A3 58308B00 MOV DWORD PTR DS:[8B3058],EAX
00887E70 C705 54308B00 0>MOV DWORD PTR DS:[8B3054],0
00887E7A C705 5C308B00 0>MOV DWORD PTR DS:[8B305C],8
00887E84 E8 0C320000 CALL PPOS.0088B095
00887E89 8985 ECFEFFFF MOV DWORD PTR SS:[EBP-114],EAX
00887E8F 83BD ECFEFFFF 0>CMP DWORD PTR SS:[EBP-114],0
00887E96 75 12 JNZ SHORT PPOS.00887EAA
00887E98 A1 361A8B00 MOV EAX,DWORD PTR DS:[8B1A36]
00887E9D 3385 85FEFFFF XOR EAX,DWORD PTR SS:[EBP-17B]
00887EA3 A3 3A1A8B00 MOV DWORD PTR DS:[8B1A3A],EAX //这就是KEY,不过是错的,按下面的方法修改EAX
00887EA8 EB 05 JMP SHORT PPOS.00887EAF
00887EAA E9 47040000 JMP PPOS.008882F6
00887EAF ^ E9 B8F4FFFF JMP PPOS.0088736C
KEY寻找关键之处:
原文中是连蒙带猜的,我这有个更好的办法,由于解密就是简单的异或,因此在代码段中必然存在真正的key值(这个也要解释?因为CODE中必然存在大量的0),直接去找吧,当然这有一定的技巧,首先要找到解码的起始位置(等UPX解压完毕),然后dump出来再找,还是麻烦?那好吧,我就说说我这个目标程序我是如何算出key(我这个不是找出来的),因为我从内存中发现该程序是delphi写的,这个就简单了(假设你找到了入口点),随便找个delphi程序,在入口特征点找到DWORD,现在与目标程序的入口点DWORD XOR一下试试,是不是很简单!
再说说Delphi的入口点:这是经验了,delphi的入口点一般都在CODE节的最后部分,而且非常明显,因此只要找到CODE节的下一个节,往上翻就找到了,不过彩虹狗采用UPX压缩后只有几个节了,因此找到这个节也有点技巧,不过你会在内存中找到完整的PE头部(在对CODE节解密的时候,看堆栈)
4)引入表
假设以上入口点,key都搞定了,你停在入口点,用ImpREC恢复,你会发现不少API被替换了:
RCC0:00890552 E8 A7 50 FF FF call
loc_8855FE
RCC0:00890557 0B 48 8B 00 dd offset unk_
8B480B
RCC0:0089055B
RCC0:0089055B E8 9E 50 FF FF call
loc_8855FE
RCC0:00890560 10 48 8B 00 dd offset unk_8B4810
RCC0:00890564 E8 95 50 FF FF call
loc_8855FE
RCC0:00890569 15 48 8B 00 dd offset unk_8B4815
看到了没,这些函数没连接到IMPORT,而其实ImpREC已将那些函数放到IMPORT表了,只是没连接上,修复这个很简单了,该函数的偏移就是(第一个函数为例)
8B480B – 00890557&0xffff = 8B42B4 , 将地址00890552处改为 FF 25 B4 42 8B 00,再用IDA看看:
RCC0:00890552 loc_890552: ; CODE XREF: sub_40136C+1 j
RCC0:00890552 jmp GetStdHandle
搞定了
,由于函数有好几百个,写个IDA脚本吧:
static main() {
auto ea;
ea = 0x0089052E;
for ( ea = 0x0089052E; ea <= 0x00892891; ) {
auto ea1,x,y;
y = 0x25ff;
ea1 = ea+5;
x = Dword(ea1);
ea1 = ea1&0xffff;
x = x - ea1;
PatchWord(ea,y);
PatchDword(ea+2,x);
ea = ea+9;
}
}
执行完毕后将二进制保存直接替换到dumped的程序中,搞定,收工。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!