• 标 题:CHiNA CrACKiNG GrOUp (7千字)
  • 作 者:娃娃[CCG]
  • 时 间:2001-9-20 14:58:11
  • 链 接:http://bbs.pediy.com

破解R!SC的CrackMe1 并写一个LOADER
                                    娃娃(NYDoll)

最近没有什么好玩的软件,不是太难的破解不了;就是太简单不值得写个过程,于是来到DDXia前辈的主页上下载了一个
r!sc所写的CrackMe1。执行一看 —— 是一个去除NAG的CrackMe,^_^ 最近正好对这个东西敢兴趣 正和我意 赶快动手吧。

先用FI检查一番,发现是PETILE2.1的壳,用专用的脱壳器可以很容易的脱壳,但是还是先不要脱壳 ^_^ 跟跟看~~~
一运行,程序马上蹦出个窗口,提示:“This program has expired  :(  please purchase the full version”,再点一下确定,程序就退出了。

立刻祭出TRW(我还是喜欢用我修改的TRW1.22增强版本 ^_^ 尽快别的大哥说不好看),载入程序,出现提示窗口,然后下断点:BPX LOCKMYTASK,点击确定按钮,你就会发现又被TRW拦下了,下命令PMODULE,你会发现TRW正好停在API函数MESSAGEBOXA的下面 ^_^ 如果你也到了这里,那你就正确了一半了。


XXXX:00406282    PUSH              DWORD 004062E0
XXXX:00406287    PUSH              DWORD 00406360
XXXX:0040628C    PUSH              BYTE +00
XXXX:0040628E    CALL  USER!MessageBoxA              <——CrackMe程序出现对话框信息所调用的API
XXXX:0040628C    POPA                                  <——TRW应该这里
XXXX:0040628C    PUSH              BYTE +00

现在我们已经找到程序出现第一个对话框时所在的地址了,接下来我们在MessageboxA函数前下断点,BPX 406282,然后重新运行程序,当程序执行到406282的时候被TRW栏到,看看这个时候程序还没有跳出对话框吧 ^_^ 接下来我们要跳过这个对话框,
用TRW向上翻,发现:

XXXX:0040622F    ADD                [EAX-41],AH
XXXX:00406232    MOV                AL,[57004062]
XXXX:00406237    CALL    KERNEL32!GetLocalTime
XXXX:0040623D    CMP                WORD [EDI],07CF
XXXX:00406242    JG                00406280
XXXX:00406244    JZ                0040624D
XXXX:00406246    CMP                WORD[EDI+02],BYTE +06
XXXX:0040624B    JNL                00406280
XXXX:0040624D    PUSH              BYTE +30
XXXX:0040624F    PUSH              DWORD 004062E0
XXXX:00406254    PUSH              DWORD 004062F0
XXXX:00406259    PUSH              BYTE +00
XXXX:0040625B    CALL    USER!MessageBoxA             
XXXX:00406261    POPA
XXXX:00406262    JMP                00401000

发现这个地方比较可疑,无缘无故的你查什么系统时间阿(KERNEL32!GetLocalTime),于是设断点BPX  40622F,重新运行程序,但是发现并没有断到40622F这里,这是什么原因呢?
猜测一:程序在这之前有一处可以跳过这里直接显示NAG对话框
猜测二:程序根本就无法执行到这个检测系统时间的地方
根据我的判断,我选择的是二,就是程序根本就不判断时间,只是一个样式,但是我们为了跳过这个NAG只好要让他判断时间试试啦(死马当成活马医吗~~~) ^_^
在406282处重新下断点,程序被拦下,下A指令改变代码,将 PUSH DWORD 004062E0 这一句改成 JMP 406237,强制使程序检测系统时间,这样程序会自动跳转到406237处继续执行,取得系统的年份,然后和1999对比,大于则出现:This program has expired  的对话框,如果不大于则出现:“This program wont run after 32st may 1999,please register and recive a NAG! free version”,07CF就是1999的十六进制值!但是由于我们改变了程序的运行方式,使程序运行到
XXXX:0040623D    CMP                WORD [EDI],07CF
这一句时检测的系统年份必定将大于1999,所以一定会跳到00406280这里执行,但是我们刚才改变了跳转,程序执行到00406282的时候还是会重新检查时间,这样就造成了程序的死循环,运行2分钟后机器一定会死机的,因此我们修正一下改动方式,
下断点BPX 4062E0,程序被拦下的时候改变语句:JMP 40624D,让他直接弹出提示的对话框对话框,然后下断点
BPX LOCKMYTASK 点击确定后再次被TRW拦下,这次应该停在第二个MessageBoxA函数的后面,就是停在406261的地方,继续单步跟踪,发现程序只要执行到406262然后跳到00401000后就好像回到一个新的PE结构的头部一样,马上就是一个GetCommandLineA
函数,这是一般的PE格式文件第一个API函数,所以如果这个时候你使用MakePE指令然后在手动修复输入表的话,生成的就完全是一个脱壳的而且没有任何期限的纯净的文件了 ^_^  可惜我不会修复输入表 :(  ◎¥#%◎#¥%……¥%……

^_^ 不过懒人有懒方法,既然不脱壳,那么我们就在程序执行到406282的时候直接改指令是程序一起把所有的NAG都跳过去不久完了吗 ^_^ 重复上面的步骤(下断点 BPX 406282,重新启动程序,被拦下后用A修改指令,改成JMP 401000)清除断点,返回Windows 哈哈 程序可以正常的运行了。

知道改的方法后 一切就简单的多了  下面我们来用MASM编写一个载入器,使程序按照我们的方法运行:


.386
.model flat,stdcall
option casemap:none

include C:\masm32\INCLUDE\windows.inc  声明!
include C:\masm32\INCLUDE\kernel32.inc
include C:\masm32\INCLUDE\user32.inc
includelib C:\masm32\LIB\kernel32.lib
includelib C:\masm32\LIB\user32.lib

DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data

AppName db 'R'SC CrackMe1 Loader',0      程序标题名称
msg_run db 'Faild to launch program',0Dh,0Ah,'...',0  程序载入错误时候的提示
msg_read db 'ReadProcessMemory error ...',0  防止内存溢出
msg_ver db 'Wrong version  ...',0    如果找不到相同的机器码则认为是无效的版本
msg_cap db 'Memory Patcher error ...',0    出错信息对话框标题
msg_write db 'WriteProcessMemory error ...',0
m_progname db 'r!sc.1.exe',0  需要载入的程序名
; 以下为关键代码段
m_addr_to_patch1 dd 00406282h  欲修改的虚拟地址
m_original_bytes1 db 068h, 0E0h, 062h, 040h, 000h    原始机器码 68E0624000
m_new_bytes1 db 0E9h, 079h, 0ADh, 0FFh, 0FFh        修改后的机器码 E979ADFFFF
m_num_of_bytes1 dd 5    一共5个字节

DlgName db "CCG",0  在补丁前显示一个对话框,标题为CCG
TimerID dd 0
TimeOutValue dd 3000      显示3000毫秒

m_loop_me dd 10  尝试修改内存次数为10次

.data?

hInstance HINSTANCE ?
read_buffer db 512 dup (?)
startinfo STARTUPINFO <>
pi PROCESS_INFORMATION <>

.code
start:

invoke GetModuleHandle,NULL
mov    hInstance,eax
invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,NULL

invoke GetStartupInfo,addr startinfo  载入程序
invoke CreateProcess,addr m_progname,NULL,NULL,NULL,FALSE,20h,NULL,NULL,addr startinfo,addr pi
test eax,eax
jz _launch_error

mov ebx,m_loop_me

_the_loop:  循环修改
invoke ReadProcessMemory,dword ptr [pi],m_addr_to_patch1,addr read_buffer,m_num_of_bytes1,0
test eax,eax
jz _read_proc_error

lea esi,read_buffer  读值并修改
lea edi,m_original_bytes1
mov ecx,m_num_of_bytes1
repz cmpsb
jnz _down
jmp _patch_the_mother
_down:
dec ebx
jnz _the_loop
jmp _wrong_ver

_patch_the_mother:  修改,若出错则跳到提示版本错误的对话框
invoke WriteProcessMemory,dword ptr [pi],m_addr_to_patch1,addr m_new_bytes1,m_num_of_bytes1,0
test eax,eax
jz _write_proc_error

jmp _exit

_launch_error:  无法载入程序时候的提示
invoke MessageBox,NULL,addr msg_run,addr msg_cap,MB_ICONSTOP+MB_OK
jmp _exit

_read_proc_error:  无法修改程序的提示
invoke MessageBox,NULL,addr msg_read,addr msg_cap,MB_ICONSTOP+MB_OK
jmp _exit

_wrong_ver:    没有找到相同的字符串则提示版本错!
invoke MessageBox,NULL,addr msg_ver,addr msg_cap,MB_ICONSTOP+MB_OK
jmp _exit

_write_proc_error:  无法写入进程的提示
invoke MessageBox,NULL,addr msg_write,addr msg_cap,MB_ICONSTOP+MB_OK

_exit:  退出程序,将存放句柄的寄存器清空
invoke CloseHandle,dword ptr [pi]
invoke CloseHandle,dword ptr [startinfo]
invoke ExitProcess,0  调用 ExitProcess 函数退出程序

DlgProc proc uses esi edi ebx,hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    .IF uMsg==WM_INITDIALOG
        invoke SetTimer,hWnd,1,TimeOutValue,NULL
        mov TimerID,eax
    .ELSEIF uMsg==WM_TIMER
                invoke KillTimer,hWnd,TimerID
                invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
    .ELSEIF uMsg==WM_CLOSE
        invoke EndDialog,hWnd,NULL
    .ELSE
        mov eax,FALSE
        ret
    .ENDIF
    mov eax,TRUE
    ret
DlgProc endp

end start

编译后5K,执行速度超快 ^_^  WinMe,MASM5下测试通过


^_^ 感谢大家看完  有什么意见欢迎交流!谨以此文献给我们可爱的CCG,希望他能蒸蒸日上(JOJO老大的话 ^_^)


                                            娃娃(NYDoll)
                        属于中国破解组织CCG(CHiNA CrACKiNG GrOUp)