相信写过驱动的朋友应该用过debugview.exe这个工具吧
你会不会觉得它的界面有点“丑”呢,还有就是观察调试信息的时候窗口要不停的ALT+TAB切换来切换去
今天心血来潮,决定将它改造一下
1,让它有个窗口置顶功能
这个很容易实现:
SetWindowPos(wnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
就ok了,我们的关键点就是要获取它的窗口句柄
2,给它加个“换肤”的功能
这里我用到一个别人开发好的dll.. ....SkinMagic.dll
SkinMagic Toolkit 是vc专用的一个皮肤开发包,有兴趣的朋友可以下下来玩玩。
下面介绍一下它在vc里面针对SDI程序的用法
(1)包含头文件SkinMagic.h,引入库文件SkinMagic.lib
(2)在CWinAPP::Instance()里初始化库,这里用到的函数是
InitSkinMagicLib(hInstance,0,0,0);和
SetWindowSkin(wnd,"MainFrame");和
SetDialogSkin("Dialog");
(3)换肤时调用LoadSkinFile(SkinFileName);进行换肤
好了,流程都知道了,下面就来动手把
我准备在主菜单里面在添加一个子菜单“附加功能”,再在这个子菜单里面添加换肤和窗口置顶几个子菜单
首先我们来修改DebugView.exe,给它的引入库添加我们要用的几个函数
这里我用到的是Stud_PE,它里面有个添加引入函数的功能,这里我就不细述了,接着我们把skin.dll和DebugView.exe放在同一个目录下(我把SkinMagic.dll改名为了skin.dll),再把几个皮肤文件也复制过来
下面我们下修改让它初始化库文件
用od载入DebugView,在他的地址空间里我们要找一个全0的空间,用来添加dll的初始化代码,我找到的是0x419531这个地址,然后我们填入下面这段代码
00419531 > $ 6A 00 push 0 ; /pModule = NULL 00419533 . E8 09223F7C call kernel32.GetModuleHandleA ; \获取Instance 00419538 . 6A 00 push 0 0041953A . E8 15CBBE0F call skin.InitSkinMagicLib ; 调用初始化函数 0041953F . 68 20CF4100 push Dbgview.0041CF20 ; ASCII "1.skin" 00419544 . E8 A1CFBE0F call skin.LoadSkinFile ; 加载一个默认的皮肤 00419549 . 68 30CF4100 push Dbgview.0041CF30 ; ASCII "Dialog" 0041954E . E8 81D1BE0F call skin.SetDialogSkin ; 调用SetDialogSkin 00419553 .^ E9 F48BFFFF jmp Dbgview.0041214C ; 跳到原oep
我们用od保存exe文件,然后用LOADPE将DebugView的oep该我我们的新oep:0x19531
运行,发现皮肤没有改变..
呵呵.因为我们该有一个初始化函数没有调用:SetWindowSkin(wnd,"MainFrame");
因为这个函数需要窗口句柄作为参数,所以我们要在主程序窗口建立后在跳过来调用这个函数,再跳回去
好的,F2重新加载程序,eip停在了我们新的oep上
bp CreateWindowExA......F9.断下两次后,停在这里
0012FCB4 00408621 /CALL 到 CreateWindowExA 来自 Dbgview.0040861B 0012FCB8 00000000 |ExtStyle = 0 0012FCBC 0041E9F8 |Class = "dbgviewClass" 0012FCC0 00423948 |WindowName = "" 0012FCC4 00CF0000 |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION 0012FCC8 000000A6 |X = A6 (166.) 0012FCCC 00000136 |Y = 136 (310.) 0012FCD0 00000379 |Width = 379 (889.) 0012FCD4 00000174 |Height = 174 (372.) 0012FCD8 00000000 |hParent = NULL 0012FCDC 00000000 |hMenu = NULL 0012FCE0 00400000 |hInst = 00400000 0012FCE4 00000000 \lParam = NULL
00408614 . 68 F8E94100 push Dbgview.0041E9F8 ; |Class = "dbgviewClass"
00408619 . 6A 00 push 0 ; |ExtStyle = 0
0040861B . FF15 A4A34100 call dword ptr ds:[<&USER32.CreateWindow>; \CreateWindowExA
00408621 . 85C0 test eax,eax
00408621出的eax就是我们需要的主窗口句柄了,我们修改它的下一条指令为jmp 00419559
00419559同样是一个0区间,接下来我们在00419559处写入如下代码:
00419559 > \A3 04DE4200 mov dword ptr ds:[42DE04],eax ; 这个是被我们覆盖掉的指令,这里要补上,还有记下这个0x42de04,后面会用到 0041955E . 83EC 0A sub esp,0A 00419561 . C60424 4D mov byte ptr ss:[esp],4D ; M 00419565 . C64424 01 61 mov byte ptr ss:[esp+1],61 ; a 0041956A . C64424 02 69 mov byte ptr ss:[esp+2],69 ; i 0041956F . C64424 03 6E mov byte ptr ss:[esp+3],6E ; n 00419574 . C64424 04 46 mov byte ptr ss:[esp+4],46 ; F 00419579 . C64424 05 72 mov byte ptr ss:[esp+5],72 ; r 0041957E . C64424 06 61 mov byte ptr ss:[esp+6],61 ; a 00419583 . C64424 07 6D mov byte ptr ss:[esp+7],6D ; m 00419588 . C64424 08 65 mov byte ptr ss:[esp+8],65 ; e 0041958D . C64424 09 00 mov byte ptr ss:[esp+9],0 ; 0 00419592 . 54 push esp ; MainFrame 00419593 . 50 push eax ; wnd 00419594 . E8 79D0BE0F call skin.SetWindowSkin ; 调用初始化 00419599 . 83C4 0A add esp,0A ; 堆栈平衡 0041959C .^ E9 8AF0FEFF jmp Dbgview.0040862B ; 跳回去

接下来,我们添加菜单如下:

下面我们的任务就是添加事件的响应了
把断点都清掉,然后bp DialogBoxParamA,f9运行,接着点击debugview的help->about->成功断下
我们在代码段跟随[esp],来到这里:
00406278 . /0F8F 410C0000 jg Dbgview.00406EBF
0040627E . |0F84 DF0B0000 je Dbgview.00406E63
00406284 . |3D 589C0000 cmp eax,9C58
00406289 . |0F8F 21050000 jg Dbgview.004067B0
0040628F . |0F84 D8040000 je Dbgview.0040676D
00406295 . |3D 519C0000 cmp eax,9C51
0040629A . |0F8F B6010000 jg Dbgview.00406456
004062A0 . |0F84 F4000000 je Dbgview.0040639A
004062A6 . |3D 479C0000 cmp eax,9C47
004062AB . |0F8F A1000000 jg Dbgview.00406352
004062B1 . |74 63 je short Dbgview.00406316
004062B3 . |83F8 68 cmp eax,68
004062B6 . |74 3B je short Dbgview.004062F3
004062B8 . |3D 2C010000 cmp eax,12C
004062BD . |0F85 DE320100 jnz Dbgview.004195A1
004062C3 . |8B8C24 740400>mov ecx,dword ptr ss:[esp+474] ; Case 12C of switch 00406273
004062CA . |8B15 70134300 mov edx,dword ptr ds:[431370] ; Dbgview.00400000
004062D0 . |6A 00 push 0 ; /lParam = NULL
004062D2 . |68 50154000 push Dbgview.00401550 ; |DlgProc = Dbgview.00401550
004062D7 . |51 push ecx ; |hOwner
004062D8 . |68 DCE34100 push Dbgview.0041E3DC ; |pTemplate = "AboutBox"
004062DD . |52 push edx ; |hInst => 00400000
004062DE . |FF15 00A44100 call dword ptr ds:[<&USER32.DialogBoxPar>; \DialogBoxParamA
004062E4 . |5F pop edi
004062E5 . |5E pop esi
004062E6 . |5D pop ebp
004062E7 . |33C0 xor eax,eax
上面的几个je就是对菜单项的id的判断,很明显id存放在eax中
我们修改0x4062bd处的跳转地址,跳到一个全0的区间,这里我选得地址是0x004195A1
接下来我们再0x004195A1出写入如下代码:
004195A1 > \60 pushad ; 保存寄存器 004195A2 . 2D 80380000 sub eax,3880 ; 我定义的几个菜单的id是3880,3881,3882,3883,,,,,, 004195A7 . 74 2B je short Dbgview.004195D4 ; 判断 004195A9 . 48 dec eax 004195AA . 74 3F je short Dbgview.004195EB 004195AC . 48 dec eax 004195AD . 74 50 je short Dbgview.004195FF 004195AF . 48 dec eax 004195B0 . 74 61 je short Dbgview.00419613 004195B2 . 48 dec eax 004195B3 . 74 72 je short Dbgview.00419627 004195B5 . 48 dec eax 004195B6 . 0F84 7F000000 je Dbgview.0041963B 004195BC . 48 dec eax 004195BD . 0F84 95000000 je Dbgview.00419658 004195C3 . 61 popad 004195C4 .^ E9 26E0FEFF jmp Dbgview.004075EF ; 跳到原处继续处理 004195C9 90 nop 004195CA 90 nop 004195CB 90 nop 004195CC 90 nop ; 这些nop是我修改代码时留下的,,没用 004195CD 90 nop 004195CE 90 nop 004195CF 90 nop 004195D0 90 nop 004195D1 90 nop 004195D2 90 nop 004195D3 90 nop 004195D4 > 68 696E0000 push 6E69 ; 1; Case 3880 of switch 00406273 004195D9 . 68 312E736B push 6B732E31 ; 压入1.skin 004195DE . 54 push esp 004195DF . E8 06CFBE0F call skin.LoadSkinFile 004195E4 . 58 pop eax 004195E5 . 58 pop eax 004195E6 . E9 81000000 jmp Dbgview.0041966C 004195EB > 68 696E0000 push 6E69 ; 2; Case 3881 of switch 00406273 004195F0 . 68 322E736B push 6B732E32 ; 压入2.skin 004195F5 . 54 push esp 004195F6 . E8 EFCEBE0F call skin.LoadSkinFile 004195FB . 58 pop eax 004195FC . 58 pop eax 004195FD . EB 6D jmp short Dbgview.0041966C 004195FF > 68 696E0000 push 6E69 ; 3; Case 3882 of switch 00406273 00419604 . 68 332E736B push 6B732E33 ; 压入3.skin 00419609 . 54 push esp 0041960A . E8 DBCEBE0F call skin.LoadSkinFile 0041960F . 58 pop eax 00419610 . 58 pop eax 00419611 . EB 59 jmp short Dbgview.0041966C 00419613 > 68 696E0000 push 6E69 ; 4; Case 3883 of switch 00406273 00419618 . 68 342E736B push 6B732E34 ; 压入4.skin 0041961D . 54 push esp 0041961E . E8 C7CEBE0F call skin.LoadSkinFile 00419623 . 58 pop eax 00419624 . 58 pop eax 00419625 . EB 45 jmp short Dbgview.0041966C 00419627 > 68 696E0000 push 6E69 ; 5; Case 3884 of switch 00406273 0041962C . 68 352E736B push 6B732E35 ; 压入5.skin 00419631 . 54 push esp 00419632 . E8 B3CEBE0F call skin.LoadSkinFile 00419637 . 58 pop eax 00419638 . 58 pop eax 00419639 . EB 31 jmp short Dbgview.0041966C 0041963B > 6A 03 push 3 ; /6; Case 3885 of switch 00406273 0041963D . 6A 00 push 0 ; |Height = 0 0041963F . 6A 00 push 0 ; |Width = 0 00419641 . 6A 00 push 0 ; |Y = 0 00419643 . 6A 00 push 0 ; |X = 0 00419645 . 6A FF push -1 ; |InsertAfter = HWND_TOPMOST 00419647 . 90 nop ; | 00419648 . 90 nop ; | 00419649 . 90 nop ; | 0041964A . A1 04DE4200 mov eax,dword ptr ds:[42DE04] ; | 0041964F . 90 nop ; | 00419650 . 50 push eax ; |hWnd => 00270756 ('DebugView - Not Connected',class='dbgviewClass') 00419651 . E8 9D039177 call user32.SetWindowPos ; \SetWindowPos 00419656 . EB 14 jmp short Dbgview.0041966C 00419658 > 6A 05 push 5 ; /7; Case 3886 of switch 00406273 0041965A . 6A 00 push 0 ; |DefDir = NULL 0041965C . 6A 00 push 0 ; |Parameters = NULL 0041965E . 68 40CF4100 push Dbgview.0041CF40 ; |FileName = "http://315712565.qzone.qq.co5.qzone.qq.com" 00419663 . 6A 00 push 0 ; |Operation = NULL 00419665 . 6A 00 push 0 ; |hWnd = NULL 00419667 . E8 7C7B1F7D call shell32.ShellExecuteA ; \ShellExecuteA 0041966C > 61 popad 0041966D . 5F pop edi 0041966E . 5E pop esi 0041966F . 5D pop ebp 00419670 . 33C0 xor eax,eax 00419672 . 5B pop ebx 00419673 . 81C4 60040000 add esp,460 00419679 . C2 1000 retn 10 ; 返回