解决ollydbg调试程序cpu应用率高达100%的问题
今天终于将ollydgb加载应用程序,运行时cpu应用率高达100%的问题解决了
在跟踪ollydbg加载程序,发现
00439616 6A 00 push 0--> 这里等待时间居然为0
上次我分析,kermaker里面的内存注册机时,这里的参数为-1,
当然了,有可以作者是特意将这里设为0的,
但看看下面
00439618 . 68 14574D>push Ollydbg.004D5714 ; |pDebugEvent = Ollydbg.004D5714
0043961D . E8 E85B07>call <jmp.&KERNEL32.WaitForDebugEvent> ; \WaitForDebugEvent
00439622 . 85C0 test eax,eax
00439624 . 75 44 jnz short Ollydbg.0043966A
00439626 . 833D 543B>cmp dword ptr ds:[4E3B54],0
0043962D . 74 27 je short Ollydbg.00439656
0043962F . 8B0D 583B>mov ecx,dword ptr ds:[4E3B58]
00439635 . 83C1 64 add ecx,64
00439638 . 3B4D CC cmp ecx,dword ptr ss:[ebp-34]
0043963B . 73 19 jnb short Ollydbg.00439656
0043963D . 6A 00 push 0 ; /lParam = 0
0043963F . 6A 00 push 0 ; |wParam = 0
00439641 . 6A 00 push 0 ; |Message = WM_NULL
00439643 . A1 5C3B4E>mov eax,dword ptr ds:[4E3B5C] ; |
00439648 . 50 push eax ; |ThreadId => 0
00439649 . E8 F25E07>call <jmp.&USER32.PostThreadMessageA> ; \PostThreadMessageA
0043964E . 33D2 xor edx,edx
00439650 . 8915 543B>mov dword ptr ds:[4E3B54],edx
00439656 > 6A 00 push 0 ; /Arg1 = 00000000
00439658 . E8 EFD405>call Ollydbg.00496B4C ; \Ollydbg.00496B4C
0043965D . 59 pop ecx
在这里居然出现了一个Sleep(0); 加了这条语句不等于没加么? 并且在被调试的程序运行时,不断的在这里断下,
所在我就将这里的0改为了0x10ms ,如果你们决得这等得太久了也可以改为1ms..
0043965E . 6A 00 push 0 ; /Timeout = 0. ms----> 把这个地方改为10,也让cpu休息一下吧!
00439660 . E8 575B07>call <jmp.&KERNEL32.Sleep> ; \Sleep
文件地址为: 38C5E
就改这一个地方问题就解决了..
再回想一下,以前用softICE跟trw2000,在win98下面调试程序时程序在中断时,
处理器的应用率就到了100%,当然了我们调试程序,大部分时间都是中断,
我的是笔记本电脑(p4 2.4G),调试程序调半个小的话,整个电脑简直成了火炉,
风扇吹个不停还是没用,特别是夏天,更是利害,后来用了ollydbg,程序在中断的时候
不会出现处理器应用率为100%的现象.尽管程序在运行时处理器应用率为100%还过得去
一直用到现在..相信大家都用过ida跟vc自带的调试工具吧!在调试程序时,
处理器是从不会出现应用率达到100%的..
------->下面介是一个简单的调试器,可做内存注册机,只适用于未加壳的程序
#define BREAKPOINT 0x4086cb
int Init()
{
HANDLE hThread;
HwndMain = hwnd;
DWORD dwThreadId, dwThrdParam = 1;
//建立线程调试程序
hThread=CreateThread(NULL,NULL,ThreadFunc,&dwThrdParam,0,&dwThreadId);
return 0;
}
int ReadMemory(HANDLE hProcess,BYTE *memory)
{
BYTE p=0xcc;
//这里保存原来的代码
ReadProcessMemory(hProcess,(LPVOID)BREAKPOINT,memory,1,NULL);
//写入int 3 中断
WriteProcessMemory(hProcess,(LPVOID)BREAKPOINT,&p,1,NULL);
return 0;
}
DWORD WINAPI ThreadFunc(LPVOID)
{
STARTUPINFO Info;
PROCESS_INFORMATION ProInfo;
DEBUG_EVENT DebugEvent;
DWORD Status;
static DWORD IsWrite=0;
CONTEXT content;
LPVOID stat;
content.ContextFlags= 0x10007;
ZeroMemory(&Info,sizeof(STARTUPINFO));
ZeroMemory(&ProInfo,sizeof(ProInfo));
ZeroMemory(&DebugEvent,sizeof(DEBUG_EVENT));
GetStartupInfo(&Info);
BYTE MemoryFromProcess;
//建立调试进程
CreateProcess(NULL,"test.exe",NULL,NULL,NULL,DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&Info,&ProInfo);
do
{
WaitForDebugEvent(&DebugEvent,-1);
switch(DebugEvent.dwDebugEventCode)
{
case 1:
if(DebugEvent.u.Exception.ExceptionRecord.ExceptionAddress==(LPVOID)BREAKPOINT && IsWrite==1)
{
GetThreadContext(ProInfo.hThread,&content);
content.Eip--;
SetThreadContext(ProInfo.hThread,&content);
//还原原来的代码,eip减1再执行..
WriteProcessMemory(ProInfo.hProcess,(LPVOID)BREAKPOINT,&MemoryFromProcess,1,NULL);
//在这里我们就可以读取内存里面的注册码了,
//当然了,我们还可以进行一些运算,算出注册码来,在这里用对话框显示..
IsWrite++;
}
Status = DBG_CONTINUE;
break;
case 6:
if(IsWrite==0)
{
ReadMemory(ProInfo.hProcess,&MemoryFromProcess);
IsWrite++;
Status =DBG_EXCEPTION_NOT_HANDLED;
}
break;
default:
Status =DBG_EXCEPTION_NOT_HANDLED;
}
ContinueDebugEvent(DebugEvent.dwProcessId,DebugEvent.dwThreadId,Status);
}while(DebugEvent.dwDebugEventCode!=5);
ExitThread(0);
return 0;
}
[课程]Linux pwn 探索篇!