有关调试寄存器DRx作用可以查Intel手册,加密软件Software技术内幕也有提及到.其中Dr0-Dr3 4个调试寄存器是存放中断地址用于设置硬件断点Dr4、Dr5英特尔保留使用功能至少现在没什么用Dr6、Dr7这两个寄存器作用是用来记录Dr0-Dr3中下断地址属性如下硬件断点读还是写或者是执行;是对字节还是对字或者是双字
我们还是以上次那个CRACKME作为例子我对它加了个简单ASPACK压缩壳
00405001 > 60 PUSHAD ; 壳入口
00405002 E8 03000000 CALL crackme.0040500A
00405007 - E9 EB045D45 JMP 459D54F7
0040500C 55 PUSH EBP
0040500D C3 RETN
...
//机器码运算
004013B4 |. E8 01080000 call <jmp.&user32.GetDlgItemTextA>
004013B9 |. 8D05 98334000 lea eax, dword ptr [403398] ; 压入机器码
004013BF |? 68 98334000 push 00403398 ; EAX中放着机器码
...
00401B90 |. 50 push eax ; EAX中就是暗码
00401B91 |? 68 7E324000 push 0040327E ; 转串
00401B96 |? 68 48334000 push 00403348
00401B9B |? E8 08000000 call <jmp.&user32.wsprfA>
00401BA0 |. 83C4 0C add esp, 0C
...
//注册码变形
0040131E |. E8 97080000 call <jmp.&user32.GetDlgItemTextA> ; 取注册码
00401323 |. 6A 08 push 8
00401325 |. 68 A8324000 push 004032A8
0040132A |. E8 B4FEFFFF call 004011E3 ; 转16进制
0040132F |. 8BF0 mov esi, eax
00401331 |. 81C6 A679F3FF add esi, FFF379A6 ; 加FFF379A6h
00401337 |. 81F6 DDAEEC04 xor esi, 4ECAEDD ; 异或4ECAEDDh
0040133D |. 81EE C78AA900 sub esi, 0A98AC7 ; 减0A98AC7h
00401343 |. 56 push esi ; 结果
00401344 |. 68 7E324000 push 0040327E ; 转串
00401349 |. 68 F8324000 push 004032F8
0040134E |. E8 55080000 call <jmp.&user32.wsprfA>
...
//对比结果
004010E8 |. 68 48334000 push 00403348 ; 机器码运算后串
004010ED |. 68 F8324000 push 004032F8 ; 注册码运算后串
004010F2 |. E8 F30A0000 call <jmp.&kernel32.lstrcmpA> ; 比较
004010F7 |. 0BC0 or eax, eax
004010F9 |. 75 19 jnz 00401114
假如以上次思路方法对004013BF和00401B90处下INT3断点当外壳把代码解密后所修改0CCh字节就会被解密后代码覆盖将导致3断点不起作用所以我们改下硬件断点
我们先让停在原始入口处再在004013BF和00401B90处下硬件断点断下后就可以为所欲为了...详细代码如下:
.586
.model flat, stdcall
option map :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
windows.inc
kernel32.inc
user32.inc
Comctl32.inc
comdlg32.inc
macros.inc
masm32.inc
lib kernel32.lib
lib user32.lib
lib Comctl32.lib
lib comdlg32.lib
lib masm32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDD_DLG1 equ 1000
IDC_NAME equ 1001
IDC_CODE equ 1002
IDC_OK equ 1005
IDC_ABOUT equ 1006
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
dwOrgOEP equ 00405001h ;原始入口
BREAK_POINT1 equ 004013BFh ;第个断点
BREAK_POINT2 equ 00401B90h ;第 2个断点
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DlgProc proto :HWND,:UINT,:WPARAM,:LPARAM
GetKey proto
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.CONST
DR0_ENABLED EQU 000000001b
LOCAL_EXACT_BPM_ENABLED EQU 100000000b
.data
MsgboxText db ' -=Author: langxang=-',0dh
db ' -=Email:[email protected]=-',0
MsgboxCaption db '有关',0
FileName db 'crackme.exe',0
3 db 0cch
value db 8 dup(?)
buffer db 8 dup(?)
old db 8 dup(?)
szFormat db "%X",0
dwCountSS dd 0
dwCountBP dd 0
ProcessInfo db "File Handle: %lx ",0dh,0Ah
db "Process Handle: %lx",0Dh,0Ah
db "Thread Handle: %lx",0Dh,0Ah
db "Image Base: %lx",0Dh,0Ah
db "Start Address: %lx",0
Startup STARTUPINFO <>
processinfo PROCESS_INFORMATION <>
.data?
UserID db 80 dup (?)
Serial db 80 dup (?)
uExitCode dd ?
hInstance HINSTANCE ?
hDlg HINSTANCE ?
startinfo STARTUPINFO <>
pi PROCESS_INFORMATION <>
DBEvent DEBUG_EVENT <>
context CONTEXT <>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_DLG1,NULL,addr DlgProc,NULL
invoke ExitProcess,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
. eaxWM_CLOSE
invoke EndDialog,hWin,0
. eaxWM_INITDIALOG
push hWin
pop hDlg
. eaxWM_COMMAND
mov eax,wParam
. eaxIDC_OK
invoke GetDlgItemText,hDlg,IDC_NAME,addr UserID,Sizeof UserID
. eax0
invoke MessageBox,hDlg,CTXT("请输入远程机器码"),CTXT("提示!"),MB_OK
.
invoke GetKey
.end
. eaxIDC_ABOUT
invoke MessageBox,hDlg,addr MsgboxText,addr MsgboxCaption,MB_OK
.end
.
mov eax,FALSE
ret
.end
mov eax,TRUE
ret
DlgProc endp
GetKey proc
pushad
;********************************************************************
; 创建进程
;********************************************************************
invoke CreateProcess, addr FileName, NULL, NULL, NULL, FALSE, DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS, NULL, NULL, addr startinfo, addr pi
. !eax
invoke MessageBox,hDlg,CTXT("不能创建进程"),CTXT("!"),MB_OK
invoke ExitProcess,NULL
.end
xor eax,eax
mov dwCountBP, eax
mov dwCountSS, eax
;********************************************************************
; 调试进程进入循环调试
;********************************************************************
.while TRUE
invoke WaitForDebugEvent, addr DBEvent, INFINITE
. DBEvent.dwDebugEventCodeEXIT_PROCESS_DEBUG_EVENT
invoke MessageBox, 0, CTXT("退出进程..."), CTXT("提示!"), MB_OK+MB_ICONINFORMATION
.
;********************************************************************
; 异常中断
;********************************************************************
. DBEvent.dwDebugEventCodeEXCEPTION_DEBUG_EVENT
. DBEvent.u.Exception.pExceptionRecord.ExceptionCodeEXCEPTION_BREAKPOINT
;********************************************************************
; 第次中断时在原始入口点处设置断点
;********************************************************************
inc dwCountBP
. dwCountBP1
invoke ReadProcessMemory, pi.hProcess, dwOrgOEP, addr old, 1, 0 ;在dwOrgOEP中读出个字节
invoke WriteProcessMemory, pi.hProcess, dwOrgOEP, addr 3, 1, 0 ;写入INT3断点
;********************************************************************
; 第 2次中断中断在起先设置原始入口点恢复代码在机器码处设置硬件断点
;********************************************************************
. dwCountBP2
mov context.ContextFlags, CONTEXT_CONTROL
invoke GetThreadContext, pi.hThread, addr context
dec context.regEip
invoke WriteProcessMemory, pi.hProcess, dwOrgOEP, addr old, 1, 0 ;恢复入口代码
invoke SetThreadContext, pi.hThread, addr context
mov context.ContextFlags, CONTEXT_DEBUG_REGISTERS
invoke GetThreadContext, pi.hThread, addr context
mov context.iDr0, BREAK_POINT1 ;设置硬件断点
mov context.iDr7, LOCAL_EXACT_BPM_ENABLED + DR0_ENABLED
invoke SetThreadContext, pi.hThread, addr context
.end
invoke ContinueDebugEvent, DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE
.continue
. DBEvent.u.Exception.pExceptionRecord.ExceptionCodeEXCEPTION_SINGLE_STEP ;单步运行模式
;********************************************************************
; 第 3次中断中断在机器码处清除断点在注册码处设置硬件断点
;********************************************************************
inc dwCountSS
.IF dwCountSS 1
mov context.ContextFlags, CONTEXT_FULL
invoke GetThreadContext, pi.hThread, addr context
mov eax,context.regEax ;机器码在EAX中
invoke WriteProcessMemory,pi.hProcess,eax,addr UserID, UserID,NULL ;写入机器码
invoke SetThreadContext, pi.hThread, addr context
; invoke ReadProcessMemory,pi.hProcess,context.regEax,addr buffer,0ch,NULL ;用于检测修改机器码是否已经生效
; invoke MessageBox,0, addr buffer,CTXT("输入新机器码为:"), MB_OK+MB_ICONINFORMATION
mov context.ContextFlags, CONTEXT_DEBUG_REGISTERS
invoke GetThreadContext, pi.hThread, addr context
mov context.iDr0, BREAK_POINT2
mov context.iDr7, LOCAL_EXACT_BPM_ENABLED + DR0_ENABLED
invoke SetThreadContext, pi.hThread, addr context
invoke ContinueDebugEvent, DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE
.continue
;********************************************************************
; 第 4次中断中断在注册码处读出注册码清除硬件断点恢复线程
;********************************************************************
. dwCountSS 2
mov context.ContextFlags, CONTEXT_FULL
invoke GetThreadContext, pi.hThread, addr context
mov context.ContextFlags, CONTEXT_FULL
mov EAX,context.regEax ;暗码在EAX中
add EAX,0A98AC7h
xor EAX,4ECAEDDh
sub EAX,0FFF379A6h
invoke wsprf,addr value,addr szFormat,eax
invoke SetDlgItemText,hDlg,IDC_CODE,addr value
mov context.iDr0, 0
mov context.iDr7, 0
invoke SetThreadContext,pi.hThread, addr context
invoke TerminateProcess,pi.hProcess,uExitCode ;强行退出
.
.end
invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId, DBG_CONTINUE
.end
.end
invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED
.endw
;********************************************************************
; 结束线程
;********************************************************************
invoke CloseHandle, pi.hThread
invoke CloseHandle, pi.hProcess
popad
ret
GetKey endp
end start
最新评论