JDPack Version 1.01 外壳完全分析笔记
【目标程序】 JDPack V1.01加壳的Win98记事本
【作 者】 cyclotron[BCG][DFCG][FCG][OCN]
用OllyDBG载入后如下:
0040D000 >PUSHAD
0040D001 CALL NOTEPAD.0040D006
0040D006 POP EBP
0040D007 MOV EDX,EBP
0040D009 SUB EBP,NOTEPAD.00402BC6 ; 取得delta
0040D00F SUB EDX,DWORD PTR SS:[EBP+403461]
0040D015 SUB EDX,6
0040D01B MOV DWORD PTR SS:[EBP+403465],EDX ; 取得基地址
0040D021 CMP DWORD PTR SS:[EBP+403469],0 ; 某重入标志
0040D028 JNZ NOTEPAD.0040D3EA
0040D02E MOV DWORD PTR SS:[EBP+403469],1 ; 置重入标志
0040D038 MOV ECX,788 ; 解码长度
0040D03D LEA ESI,DWORD PTR SS:[EBP+402C18] ; 加密代码的起始地址,我这里是0040D058
0040D043 MOV AL,BYTE PTR SS:[EBP+403460]
0040D049 MOV BL,BYTE PTR DS:[ESI]
0040D04B XOR AL,BL ; 简单的异或解密运算
0040D04D MOV BYTE PTR DS:[ESI],AL
0040D04F MOV BYTE PTR SS:[EBP+403460],BL ; 保存解密前的代码
0040D055 INC ESI
0040D056 LOOPD SHORT NOTEPAD.0040D043 ; 随着循环的进行对下面的代码进行解密
0040D058 PUSHFD ; 标志位入栈,这里不能单步通过
0040D059 POP EAX
0040D05A TEST AH,1 ; 检测单步标志
0040D05D JE SHORT NOTEPAD.0040D066
0040D05F XOR BYTE PTR SS:[EBP+402FD7],0FF ; 发现跟踪企图后将下面的一句关键代码破坏
0040D066 MOV ESI,DWORD PTR SS:[EBP+403201] ; 原文件的区块数目
0040D06C MOV EAX,EBP ; delta
0040D06E PUSH ESI
0040D06F PUSH EAX ; 保存偏移量
0040D070 MOV ECX,DWORD PTR DS:[EAX+403209] ; 申请空间的大小
0040D076 PUSH 4
0040D078 PUSH 1000
0040D07D PUSH ECX
0040D07E PUSH 0 ; 操作系统指定分配空间的地址
0040D080 CALL DWORD PTR SS:[EBP+4033EC] ; kernel32.VirtualAlloc
0040D086 MOV DWORD PTR SS:[EBP+4031E1],EAX ; 保存空间的首地址
0040D08C POP EAX
0040D08D POP ESI
0040D08E PUSH ESI
0040D08F PUSH EAX
0040D090 MOV ESI,DWORD PTR DS:[EAX+403205] ; 代码块偏移量
0040D096 MOV EDX,DWORD PTR SS:[EBP+403465] ; 映象基地址
0040D09C MOV ECX,DWORD PTR DS:[EAX+403209] ; 解密块的大小
0040D0A2 ADD ESI,EDX
0040D0A4 PUSHAD
0040D0A5 MOV EDI,ESI
0040D0A7 XOR EAX,EAX
0040D0A9 LODS BYTE PTR DS:[ESI] ; 载入代码块数据至al
0040D0AA XOR AL,BYTE PTR SS:[EBP+402FD7] ; 加密代码块的数据
0040D0B0 STOS BYTE PTR ES:[EDI] ; 存回代码块
0040D0B1 LOOPD SHORT NOTEPAD.0040D0A9
0040D0B3 POPAD
0040D0B4 MOV EDI,DWORD PTR SS:[EBP+4031E1] ; 这是前面用VirtualAlloc分配的内存空间
0040D0BA REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; 保存加密后的数据
0040D0BC MOV ESI,DWORD PTR SS:[EBP+4031E1] ; 加密数据的保存位置
0040D0C2 MOV EDI,DWORD PTR DS:[EAX+403205] ; 代码块偏移量
0040D0C8 ADD EDI,EDX
0040D0CA PUSH EDI
0040D0CB PUSH ESI
0040D0CC CALL NOTEPAD.0040D4BD ; 将代码块的数据还原
0040D0D1 POP ESI
0040D0D2 POP EDI
0040D0D3 POP EAX
0040D0D4 POP ESI
0040D0D5 PUSH ESI
0040D0D6 PUSH EAX
0040D0D7 MOV ECX,DWORD PTR DS:[EAX+403209] ; 申请空间的大小
0040D0DD MOV ESI,DWORD PTR SS:[EBP+4031E1] ; 动态申请的内存空间
0040D0E3 PUSH 4000
0040D0E8 PUSH ECX
0040D0E9 PUSH ESI
0040D0EA CALL DWORD PTR SS:[EBP+4033F0] ; kernel32.VirtualFree释放空间
0040D0F0 POP EAX
0040D0F1 POP ESI
0040D0F2 ADD EAX,8 ; delta+8
0040D0F5 DEC ESI ; 区块数递减SI
0040D0F6 JNZ NOTEPAD.0040D06E ; 上述循环依次对每个section进行解码
0040D0FC CMP DWORD PTR SS:[EBP+4031E9],0 ; 是否有重定位数据?
0040D103 JE NOTEPAD.0040D193
0040D109 MOV EDX,DWORD PTR SS:[EBP+403465] ; 当前映象基地址
0040D10F MOV EAX,DWORD PTR SS:[EBP+4031E5] ; 理想映象基地址
0040D115 SUB EDX,EAX
0040D117 JE SHORT NOTEPAD.0040D193 ; 是否需要重定位?
..........
..........
..........
0040D191 JMP SHORT NOTEPAD.0040D12C
0040D193 LEA EBX,DWORD PTR SS:[EBP+403389] ; "user32.dll"
0040D199 PUSH EBX
0040D19A CALL DWORD PTR SS:[EBP+4033E8] ; 调用kernel32.LoadLibraryA 加载动态链接库
0040D1A0 PUSH EAX ; 保存库的句柄
0040D1A1 LEA EBX,DWORD PTR SS:[EBP+403331] ; "MessageBoxA"
0040D1A7 PUSH EBX
0040D1A8 PUSH EAX
0040D1A9 CALL DWORD PTR SS:[EBP+4033E0] ; 调用kernel32.GetProcAddress 取得函数地址
0040D1AF MOV DWORD PTR SS:[EBP+4031D5],EAX ; 保存到全局变量
0040D1B5 POP EAX
0040D1B6 LEA EBX,DWORD PTR SS:[EBP+40333D] ; "wsprintfA"
0040D1BC PUSH EBX
0040D1BD PUSH EAX
0040D1BE CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D1C4 MOV DWORD PTR SS:[EBP+4031D9],EAX
0040D1CA LEA EBX,DWORD PTR SS:[EBP+4033F8] ; "kernel32.dll"
0040D1D0 PUSH EBX
0040D1D1 CALL DWORD PTR SS:[EBP+4033E4] ; kernel32.GetModuleHandleA
0040D1D7 PUSH EAX
0040D1D8 LEA EBX,DWORD PTR SS:[EBP+403347] ; "ExitProcess"
0040D1DE PUSH EBX
0040D1DF PUSH EAX
0040D1E0 CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D1E6 MOV DWORD PTR SS:[EBP+4031C5],EAX
0040D1EC POP EAX
0040D1ED PUSH EAX
0040D1EE LEA EBX,DWORD PTR SS:[EBP+403361] ; "CreateFileA"
0040D1F4 PUSH EBX
0040D1F5 PUSH EAX
0040D1F6 CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D1FC MOV DWORD PTR SS:[EBP+4031C1],EAX
0040D202 POP EAX
0040D203 PUSH EAX
0040D204 LEA EBX,DWORD PTR SS:[EBP+403353] ; "GetVersionExA"
0040D20A PUSH EBX
0040D20B PUSH EAX
0040D20C CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D212 MOV DWORD PTR SS:[EBP+4031C9],EAX
0040D218 POP EAX
0040D219 PUSH EAX
0040D21A LEA EBX,DWORD PTR SS:[EBP+40336D] ; "VirtualProtect"
0040D220 PUSH EBX
0040D221 PUSH EAX
0040D222 CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D228 MOV DWORD PTR SS:[EBP+4031CD],EAX
0040D22E POP EAX
0040D22F LEA EBX,DWORD PTR SS:[EBP+40337C] ; "GetTickCount"
0040D235 PUSH EBX
0040D236 PUSH EAX
0040D237 CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D23D MOV DWORD PTR SS:[EBP+4031D1],EAX
0040D243 LEA EBX,DWORD PTR SS:[EBP+40346D] ; OSVERSIONINFO结构体的指针
0040D249 MOV DWORD PTR DS:[EBX],94 ; OSVERSIONINFO结构体的大小
0040D24F PUSH EBX
0040D250 CALL DWORD PTR SS:[EBP+4031C9] ; kernel32.GetVersionExA
0040D256 LEA EBX,DWORD PTR SS:[EBP+40346D]
0040D25C CMP DWORD PTR DS:[EBX+10],1 ; Win98?
0040D260 JE SHORT NOTEPAD.0040D276
0040D262 CMP DWORD PTR DS:[EBX+10],2 ; WinNT?
0040D266 JE SHORT NOTEPAD.0040D26A
0040D268 JMP SHORT NOTEPAD.0040D284
0040D26A CALL NOTEPAD.0040D44E ; 简单地调用CreateFile检测SoftICE
{
0040D44E PUSH 0
0040D450 PUSH 80
0040D455 PUSH 3
0040D457 PUSH 0
0040D459 PUSH 0
0040D45B PUSH 80000000
0040D460 LEA EBX,DWORD PTR SS:[EBP+403394]
0040D466 PUSH EBX ; "\\.\ntice"
0040D467 CALL DWORD PTR SS:[EBP+4031C1] ; 调用CreateFileA检测SoftICE
0040D46D CMP EAX,-1
0040D470 JE SHORT NOTEPAD.0040D478
0040D472 CALL NOTEPAD.0040D47B
0040D477 RETN
0040D478 XOR EAX,EAX ; 未发现调试器
0040D47A RETN
}
0040D26F CMP EAX,-1
0040D272 JNZ SHORT NOTEPAD.0040D284
0040D274 JMP SHORT NOTEPAD.0040D280
0040D276 CALL NOTEPAD.0040D418
0040D27B CMP EAX,-1
0040D27E JNZ SHORT NOTEPAD.0040D284
0040D280 POPAD
0040D281 XOR EAX,EAX
0040D283 RETN
0040D284 MOV EDX,DWORD PTR SS:[EBP+403465] ; 映象基地址
0040D28A MOV ESI,DWORD PTR SS:[EBP+4031F1] ; 输入表的偏移量,开始处理输入表
0040D290 ADD ESI,EDX
0040D292 MOV EAX,DWORD PTR DS:[ESI+C] ; DllName指针
0040D295 OR EAX,EAX
0040D297 JE NOTEPAD.0040D3EA
0040D29D ADD EAX,EDX
0040D29F MOV DWORD PTR SS:[EBP+4031BD],EAX ; 保存DllName地指针
0040D2A5 MOV EBX,EAX
0040D2A7 PUSH EAX
0040D2A8 CALL DWORD PTR SS:[EBP+4033E4] ; kernel32.GetModuleHandleA
0040D2AE OR EAX,EAX ; 是否已经加载?
0040D2B0 JNZ SHORT NOTEPAD.0040D307
0040D2B2 PUSH EBX
0040D2B3 CALL DWORD PTR SS:[EBP+4033E8] ; 没有加载就调用kernel32.LoadLibraryA加载
0040D2B9 OR EAX,EAX ; 加载成功?
0040D2BB JNZ SHORT NOTEPAD.0040D307
..........
..........
..........
0040D307 MOV DWORD PTR SS:[EBP+4031F9],EAX ; 保存Dll的句柄
0040D30D MOV DWORD PTR SS:[EBP+4031FD],0 ; IAT地址表的偏移指针
0040D317 MOV EDX,DWORD PTR SS:[EBP+403465] ; 映象基地址
0040D31D MOV EAX,DWORD PTR DS:[ESI] ; OriginalFirstThunk
0040D31F OR EAX,EAX
0040D321 JNZ SHORT NOTEPAD.0040D326
0040D323 MOV EAX,DWORD PTR DS:[ESI+10] ; FirstThunk
0040D326 ADD EAX,EDX ; 加上映象基地址
0040D328 ADD EAX,DWORD PTR SS:[EBP+4031FD]
0040D32E MOV EBX,DWORD PTR DS:[EAX] ; 引入函数名指针的偏移量形式
0040D330 MOV EDI,DWORD PTR DS:[ESI+10] ; FirstThunk
0040D333 ADD EDI,EDX ; 加上映象基地址
0040D335 ADD EDI,DWORD PTR SS:[EBP+4031FD]
0040D33B TEST EBX,EBX
0040D33D JE NOTEPAD.0040D3DC ; 从这里跳出填充IAT的循环
0040D343 TEST EBX,80000000 ; 以序数引入?
0040D349 JNZ SHORT NOTEPAD.0040D352
0040D34B ADD EBX,EDX ; 加上映象基地址
0040D34D ADD EBX,2 ; 跳过序号(hint)域
0040D350 JMP SHORT NOTEPAD.0040D367
0040D352 AND EBX,7FFFFFFF
0040D358 PUSH EBX
0040D359 PUSH DWORD PTR SS:[EBP+4031F9]
0040D35F CALL DWORD PTR SS:[EBP+4033E0]
0040D365 JMP SHORT NOTEPAD.0040D37F
0040D367 PUSH EBX ; 引入函数名的指针
0040D368 PUSH DWORD PTR SS:[EBP+4031F9] ; Dll句柄
0040D36E CALL DWORD PTR SS:[EBP+4033E0] ; kernel32.GetProcAddress
0040D374 JMP SHORT NOTEPAD.0040D37A
0040D376 MOV BYTE PTR DS:[EBX],0 ; 清空函数名字符串
0040D379 INC EBX
0040D37A CMP BYTE PTR DS:[EBX],0 ; 函数名是否结束?
0040D37D JNZ SHORT NOTEPAD.0040D376
0040D37F OR EAX,EAX ; 引入函数地址
0040D381 JNZ SHORT NOTEPAD.0040D3CE
..........
..........
..........
0040D3CE MOV DWORD PTR DS:[EDI],EAX ; 将函数地址装入FirstThunk指向的IAT
0040D3D0 ADD DWORD PTR SS:[EBP+4031FD],4 ; IAT地址表的指针递增
0040D3D7 JMP NOTEPAD.0040D317
0040D3DC ADD ESI,14 ; 下一组IID
0040D3DF MOV EDX,DWORD PTR SS:[EBP+403465] ; 映象基地址
0040D3E5 JMP NOTEPAD.0040D292
0040D3EA PUSH 30
0040D3EC LEA EBX,DWORD PTR SS:[EBP+40324D] ; 字符串"Unregistered JDPack"
0040D3F2 PUSH EBX
0040D3F3 LEA EBX,DWORD PTR SS:[EBP+403261] ; 字符串"This file PACKED by Unregistered..."
0040D3F9 PUSH EBX
0040D3FA PUSH 0
0040D3FC CALL DWORD PTR SS:[EBP+4031D5] ; user32.MessageBoxA
0040D402 MOV EDX,DWORD PTR SS:[EBP+403465] ; 映象基地址
0040D408 MOV EAX,DWORD PTR SS:[EBP+4031ED] ; OEP偏移量
0040D40E ADD EAX,EDX
0040D410 MOV DWORD PTR SS:[ESP+1C],EAX
0040D414 POPAD
0040D415 PUSH EAX ; OEP入栈
0040D416 RETN ; 进入原始程序代码