首页
社区
课程
招聘
解决ollydbg调试程序cpu应用率高达100%的问题
发表于: 2006-3-26 12:49 11614

解决ollydbg调试程序cpu应用率高达100%的问题

2006-3-26 12:49
11614

解决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;
}


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (18)
雪    币: 234
活跃值: (370)
能力值: ( LV9,RANK:530 )
在线值:
发帖
回帖
粉丝
2
不错!
2006-3-26 13:23
0
雪    币: 211
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
强 马上试试
2006-3-26 13:24
0
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
4
学习!支持楼主!
2006-3-26 13:34
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个还是不要随便改,重则会出问题。
2006-3-26 13:40
0
雪    币: 333
活跃值: (369)
能力值: ( LV12,RANK:490 )
在线值:
发帖
回帖
粉丝
6
最初由 鸡蛋壳 发布
这个还是不要随便改,重则会出问题。


我的没出问题..
测试过了..
2006-3-26 14:06
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
测试不够完整
2006-3-26 14:21
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
最初由 FlyToTheSpace 发布
我的没出问题..
测试过了..


你就这样算测试OK?

虽然我没用证据证明有问题,但显然这个参数关系到扑捉以及刷新事件问题。
2006-3-26 14:28
0
雪    币: 333
活跃值: (369)
能力值: ( LV12,RANK:490 )
在线值:
发帖
回帖
粉丝
9
刷新事件总会有等待时间的吧!,
不会一直刷下去吧!消息有那么多么..
        while (GetMessage (&msg, NULL, 0, 0))
        {
                TranslateMessage (&msg) ;
                DispatchMessage (&msg) ;
        }
在这个消息处理里面也是有等待时间的..
2006-3-26 14:37
0
雪    币: 333
活跃值: (369)
能力值: ( LV12,RANK:490 )
在线值:
发帖
回帖
粉丝
10
调试器把处理器资源都占了,其它程序运行,慢得要命..
调试一些程序还会出问题..
如果是这样的话,我宁愿选择其它的调试器!
vc自带的调试器,就不会出现这个问题, 缺点就是功能太少了.
W32dsm反编译在查找字符串之后,处理器占用资源就到
100%了,为些不得不将它关了,不然开了它,其它程序就会运行不正
常了.正是这个原因,我在一年多前,就不用这个工具反编译了..
2006-3-26 14:49
0
雪    币: 207
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
先这么改了,有问题再改回来
2006-3-26 16:54
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
在UNIX下似乎有一种方法来对用户分配CUP资源,就像网通给ADSL用户分配带宽一样.有没有一种办法来给程序分配资源呢?比如,某程序最多可得到40%的CPU....
2006-3-26 17:10
0
雪    币: 172
活跃值: (212)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习了谢谢
2006-3-26 20:14
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不错,我这里也经常出现这种情况,试试
2006-3-27 08:05
0
雪    币: 257
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
不得不顶,正在愁这个问题了
2006-3-27 08:40
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
降低OD进程的优先级,就不会觉得系统卡,同时我注意了一下,OD在中断时,CPU是不独占的,只有跟踪才会100%,我觉得应该有sleep 0的根据。
2006-3-27 10:05
0
雪    币: 333
活跃值: (369)
能力值: ( LV12,RANK:490 )
在线值:
发帖
回帖
粉丝
17
VOID Sleep(  DWORD dwMilliseconds);

Parameters
dwMilliseconds

[in] Minimum time interval for which execution is to be suspended, in milliseconds.
A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.

A value of INFINITE indicates that the suspension should not time out.

WaitForDebugEvent
BOOL WaitForDebugEvent(
  LPDEBUG_EVENT lpDebugEvent,
  DWORD dwMilliseconds
);
Parameters
lpDebugEvent
[out] Pointer to a DEBUG_EVENT structure that receives information about the debugging event.
dwMilliseconds
[in] Number of milliseconds to wait for a debugging event. If this parameter is zero, the function tests for a debugging event and returns immediately. If the parameter is INFINITE, the function does not return until a debugging event has occurred.
2006-3-27 15:29
0
雪    币: 356
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
CPU占用率应该和DEBUG事件的响应速度是一对矛盾吧。使用dbghelp.dll的调试API的调试器一般都有一个while(1)的主循环。里面不断对调试事件进行响应。WaitForDebugEvent等待调试时间发生,sleep用来交出CPU的使用权。如果把延时参数改大,对DEBUG事件的响应肯定有影响(特别是更改那个sleep的参数。)。对普通int3断点可能还好说点,毕竟有SEH在那里挡住了。但是对于硬件断点呢?万一你睡的时间太长了,在两次WaitForDebugEvent之间已经有了DR0-DR3的对应地址的调试事件产生了怎么办?
2006-3-28 14:59
0
雪    币: 356
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
再说了sleep(0)并不等同于没有。只要调用了sleep函数,就有同步信号量被释放,CPU控制权就会有个交接过程,虽然时间参数是0ms,但是并不意味着在sleep语句执行之前的CPU时刻=sleep执行之后的CPU时刻.
2006-3-28 15:01
0
游客
登录 | 注册 方可回帖
返回
//