首页
论坛
专栏
课程

给记事本添加"总在前面"功能[原创]

2006-3-20 15:57 16448

给记事本添加"总在前面"功能[原创]

2006-3-20 15:57
16448
标题:给记事本添加"总在前面"功能
使用工具:OD, LoadPE,WindowsXP英文版里面的记事本程序
其实在本论坛里面,已经有很多高手做过这个工作了 呵呵 我今天也来做一个 方法还是大同小异的 下面我们开始工作
给Windows应用程序添加功能主要是通过修改消息处理来实现.所以我们首先要找到的就是windows消息处理过程 然后在这里修改使其能够处理我们添加的消息,然后实现我们自己的功能
要让窗口总在最上面需要使用一个函数 函数名字是:SetWindowPos
函数原型:
BOOL SetWindowPos(          HWND hWnd,
    HWND hWndInsertAfter,
    int X,
    int Y,
    int cx,
    int cy,
    UINT uFlags
);
首先用资源修改工具给记事本添加一个菜单项 ID可以随便 我用的是1C十进制就是28
知道了函数原型和添加了菜单项目后我们可以开始工作了.
用OD打开记事本 下断 bp RegisterClassExW  F9运行 然后断了下来
观察当前堆栈
0007FDE4   01004556  /CALL 到 RegisterClassExW 来自 NOTEPAD.01004550
0007FDE8   0007FDF0  \pWndClassEx = 0007FDF0
0007FDEC   77D49B69  USER32.LoadCursorW
0007FDF0   00000030
0007FDF4   00000000
0007FDF8   01003429  NOTEPAD.01003429
0007FDFC   00000000
0007FE00   00000000
0007FE04   01000000  NOTEPAD.01000000
0007FE08   00980761
0007FE0C   00010013
0007FE10   00000006
0007FE14   00000001
0007FE18   01009020  UNICODE

呵呵 01003429就是我们要的地址,为什么是这个地址呢 用MSDN看一个RegisterClassExW的原型就有答案了
Enter 来到01003429可以看到这里就是消息处理函数的入口,OD已经在注释里面给我们指出了每一个case了,我们来找个合适的位置处理我们的消息吧  ,拉着滚动条向下可以看到一个一个的case 和消息处理
哈哈 我找了这个位置
01002EA5   . /E9 BD040000   JMP NOTEPAD.01003367
01002EAA   > |83FF 1A       CMP EDI,1A
01002EAD   . |0F8F 9D580000 JG NOTEPAD.01008750
01002EB3   . |0F84 55010000 JE NOTEPAD.0100300E
01002EB9   . |83EF 16       SUB EDI,16
01002EBC   . |0F84 F4000000 JE NOTEPAD.01002FB6

这里有个和1A判断的 而我们的ID是1C 所以很接近读了一下代码发现可以开始了 我们的1C是大于1A的 所以只要修改
01002EAD   . /0F8F 9D580000 JG NOTEPAD.01008750

这个跳转 让它跳到我们的代码就好了 OK  注意:这里消息放在EDI里面
我们就在记事本的空白地方找个位置写我们的代码吧我是从1008750开始的
下面是我的代码
01008747      00            DB 00
01008748      00            DB 00
01008749      00            DB 00
0100874A   .  00000000      DD 00000000     ;这个位置是用来记录当前的状态的
0100874E      00            DB 00
0100874F      00            DB 00
01008750   >  83FF 1C       CMP EDI,1C     ;比较是不是我们要的消息
01008753   .  74 05         JE SHORT NOTEPAD.0100875A  ;如果是就用我们的代码来处理消息
01008755   .^ E9 BFA8FFFF   JMP NOTEPAD.01003019       ;不是就回到原来的跳转位置
0100875A   >  52            PUSH EDX        ;要用它来做临时寄存器用所以先入栈   
0100875B   .  8B15 4A870001 MOV EDX,DWORD PTR DS:[100874A]   ;把当前的状态放进去
01008761   .  6A 13         PUSH 13                          ;参数压栈
01008763   .  6A 00         PUSH 0
01008765   .  6A 00         PUSH 0
01008767   .  6A 00         PUSH 0
01008769   .  6A 00         PUSH 0
0100876B   .  83FA 00       CMP EDX,0                        ;比较当前的状态如果是在最上面状态就取消不是就使他在最上面
0100876E   .  75 0A         JNZ SHORT NOTEPAD.0100877A       ;0不是最上面  1最上面
01008770   .  6A FF         PUSH -1
01008772   .  6A 01         PUSH 1
01008774   .  8F05 4A870001 POP DWORD PTR DS:[100874A]       ;修改状态标记
0100877A   >  74 0A         JE SHORT NOTEPAD.01008786
0100877C   .  6A FE         PUSH -2
0100877E   .  6A 00         PUSH 0
01008780   .  8F05 4A870001 POP DWORD PTR DS:[100874A]       ;修改状态标记
01008786   >  FF35 30980001 PUSH DWORD PTR DS:[1009830]              ; 记事本的hWnd
0100878C   .  FF15 1A400101 CALL DWORD PTR DS:[<&USER32.SetWindowPos>; call  
01008792   .  5A            POP EDX                          ;和前面入栈对照 自己压的自己出
01008793   .^ E9 6DA4FFFF   JMP NOTEPAD.01002C05             ;执行完毕后返回

然后在OD的反汇编窗口点右键-->复制到可执行文件-->右键保存文件(全部)-->选择你要保存的文件名-->保存
工作结束
注意事项:
其实SetWindowsPos这个函数记事本本身是没有的 所以有两种方法来使用它
1:用LoadPE等工具给它添加这个函数 该函数在USER32.DLL里面
2:使用下面的方法
  push USER32.DLL
  call GetModuleHandleA
  push SetWindowsPos
  push eax
  call GetProcAddress
  call eax  ;eax就是我们要的函数SetWindowPos了 (不要像我这么写无法运行的 你要自己写)
感谢本坛的ohuangkeo大虾我有参考他的方法,还有一个大虾记不起名字了哈 谢谢了
后:^_^我的比他们两个的代码更少一点."总在最上"会遮挡下面内容的 怎么办那就再添加一个透明功能吧
要让一个窗口透,首先要更改窗口样式,要用的函数是GetWindowLong() SetWindowLong() SetLayeredWindowAttributes()
思路和上面一样判断消息处理之下面的是我随便写的代码 我还没有实际测试
使记事本透明
cmp edi,1D
je ********
jnz **********
push -14
push hWnd
call GetWindowLong
OR eax,80000
push eax
push -14
push hWnd
call SetWindowLong
push 2
push 96
push 0
push hWnd
call SetLayeredWindowAttributes

取消透明
push -14
push hWnd
call GetWindowLong
and eax,fff7ffff
push eax
push -14
push hWnd
call SetWindowLong
有时间弄下试试

[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最新回复 (38)
17521 1 2006-3-20 16:01
2
0
上传一个图片和做好的文件
上传的附件:
ViperDodge 1 2006-3-20 18:19
3
0
On Top这个菜单是怎么加上去的?
lnn1123 13 2006-3-20 18:27
4
0
最初由 ViperDodge 发布
On Top这个菜单是怎么加上去的?

编辑资源菜单加上去的
ViperDodge 1 2006-3-20 19:08
5
0
哦,原来资源编辑器加上去,谢谢lnn1123
andy00 4 2006-3-22 12:23
6
0
支持,加精,多出点PE DIY上的文章
ggosgg 2006-3-22 13:09
7
0
不错.很值得学习....
roxhaiy 1 2006-3-22 14:20
8
0
虽然还没加精,但我认为这是精品!
mikydoll 2006-3-22 17:01
9
0
啊哦。大大,感谢你的文章,我收获很大,但我在最后保存的时候没办法啊,
点右健-》复制 以后有个复制到煎切版,一个是文件,但文件里不能保存成EXE啊。我该怎么做啊?
17521 1 2006-3-22 17:24
10
0
最初由 mikydoll 发布
啊哦。大大,感谢你的文章,我收获很大,但我在最后保存的时候没办法啊,
点右健-》复制 以后有个复制到煎切版,一个是文件,但文件里不能保存成EXE啊。我该怎么做啊?


右键 选择"复制到可执行文件" 不是复制
Prudence 2006-3-22 19:18
11
0
多谢大家关照
清风ll 2006-3-23 01:17
12
0
这里太多高人,老大,以后就在这里混了,请多指教哦.
wdx 2006-3-23 11:02
13
0
谢谢,不错
vov369 2006-3-23 11:25
14
0
谢谢了  收藏
WAKU 7 2006-3-23 11:42
15
0
收藏收藏
asd 2006-3-23 12:34
16
0
支持,学习了
hxsoft 2006-3-23 13:37
17
0
强,收藏学习一下。Thank you very much!
wdx 2006-3-23 14:25
18
0
在“On Top”后加一个对号标记“√”,不知又如何操作
wangluosus 2006-3-25 13:23
19
0
最初由 wdx 发布
在“On Top”后加一个对号标记“√”,不知又如何操作


对对对,我也想知道这个代码,当置顶时就打钩,不置顶时就没有钩,这个应该是在比较的时候加入的,但是具体的不太清楚,不知道楼主还会看这个帖子不?或者哪位实践过让大家分享一下
k99992002 2006-3-25 18:02
20
0
记得看雪老大弄过这个!
wangluosus 2006-3-25 18:03
21
0
最初由 k99992002 发布
记得看雪老大弄过这个!


在哪篇文章嘛??我找不到啊
ah007 2 2006-3-25 19:10
22
0
好!
17521 1 2006-3-25 21:30
23
0
看到很多人希望菜单前面加个标记 这个其实我也不知道怎么加
找了个API没有试 大家有兴趣试试看 偶要准备下周的笔试 现在没有空 抱歉哈

Sets or removes the specified menu item's check mark attribute and shows or hides the corresponding control. The function adds a check mark to the specified menu item if it does not have one and then displays the corresponding control. If the menu item already has a check mark, the function removes the check mark and hides the corresponding control.

Syntax

BOOL ShowHideMenuCtl(          HWND hWnd,
    UINT_PTR uFlags,
    LPINT lpInfo
);
Parameters

hWnd
Handle to the window that contains the menu and controls.
uFlags
Identifier of the menu item to receive or lose a check mark.
lpInfo
Pointer to an array that contains pairs of values. The second value in the first pair must be the handle to the application's main menu. Each subsequent pair consists of a menu item identifier and a control window identifier. The function searches the array for a value that matches uFlags and, if the value is found, checks or unchecks the menu item and shows or hides the corresponding control.
Return Value

Returns nonzero if successful, or zero otherwise.

Function Information

Header commctrl.h
Import library comctl32.lib
Minimum operating systems Windows NT 3.51, Windows 95
peaceclub 6 2006-3-25 22:13
24
0
嘿嘿,借用一下编号[ 17521 ]的代码,加√号


01008750 > 83FF 1C CMP EDI,1C
01008753 .^ 0F85 C0A8FFFF JNZ notepad.01003019
01008759 . 52 PUSH EDX ; Case 1C of switch 01002BBE
0100875A . 8B15 4A870001 MOV EDX,DWORD PTR DS:[100874A]
01008760 . 6A 13 PUSH 13
01008762 . 6A 00 PUSH 0
01008764 . 6A 00 PUSH 0
01008766 . 6A 00 PUSH 0
01008768 . 6A 00 PUSH 0
0100876A . 83FA 00 CMP EDX,0
0100876D . 75 0A JNZ SHORT notepad.01008779
0100876F . 6A FF PUSH -1
01008771 . 6A 08 PUSH 8 //****注意,这里改为8 MF_Checked
01008773 . 8F05 4A870001 POP DWORD PTR DS:[100874A]
01008779 > 74 0A JE SHORT notepad.01008785
0100877B . 6A FE PUSH -2
0100877D . 6A 00 PUSH 0
0100877F . 8F05 4A870001 POP DWORD PTR DS:[100874A]
01008785 > FF35 30980001 PUSH DWORD PTR DS:[1009830] ; |hWnd = NULL
0100878B . FF15 1A300101 CALL DWORD PTR DS:[<&USER32.SetWindowPos>; \SetWindowPos
01008791 . 5A POP EDX
01008792 . 60 PUSHAD
01008793 . 33DB XOR EBX,EBX
01008795 . B3 1C MOV BL,1C
01008797 . 8B35 4A870001 MOV ESI,DWORD PTR DS:[100874A]
0100879D . FF35 30980001 PUSH DWORD PTR DS:[1009830] ; /hWnd = NULL
010087A3 . FF15 64120001 CALL DWORD PTR DS:[<&USER32.GetMenu>] ; \GetMenu
010087A9 . 56 PUSH ESI ; /Flags => MF_BYCOMMAND|MF_ENABLED|MF_STRING
010087AA . 8B35 60120001 MOV ESI,DWORD PTR DS:[<&USER32.GetSubMen>; |USER32.GetSubMenu //**取handle
010087B0 . 53 PUSH EBX ; |ItemId
010087B1 . 8BF8 MOV EDI,EAX ; |
010087B3 . 6A 03 PUSH 3 ; |/Pos = 3
010087B5 . 57 PUSH EDI ; ||hMenu
010087B6 . FFD6 CALL ESI ; |\GetSubMenu
010087B8 . 50 PUSH EAX ; |hMenu
010087B9 . FF15 48120001 CALL DWORD PTR DS:[<&USER32.CheckMenuIte>; \CheckMenuItem //**关键API
010087BF . 61 POPAD
010087C0 .^ E9 40A4FFFF JMP notepad.01002C05

peaceclub 6 2006-3-25 22:20
25
0
传一个中文XP sp2下弄好的Notepad
上传的附件:
17521 1 2006-3-25 23:01
26
0
楼上弄出来了 学习学习 原来用的是CheckMenuItem   偶不知道用这个
lzpjes 2006-3-26 22:42
27
0
应该好好学习,但为何不用XP中文版的记事本呢?
wenglingok 26 2006-3-27 09:10
28
0
最初由 lzpjes 发布
应该好好学习,但为何不用XP中文版的记事本呢?


一样一样
wangluosus 2006-3-27 15:16
29
0
可是为什么我用资源器把“总在最前”移到跟帮助、查看等并排的时候,“总在最前”还是为menuitem,而且ID还是28,置顶的功能也还可以使用,但是又没有加√号了,这到底怎么回事呢??
如图
peaceclub 6 2006-3-27 15:44
30
0
最初由 wangluosus 发布
可是为什么我用资源器把“总在最前”移到跟帮助、查看等并排的时候,“总在最前”还是为menuitem,而且ID还是28,置顶的功能也还可以使用,但是又没有加√号了,这到底怎么回事呢??
如图

√号问题请看24楼

还有"总在最前"应该放在子菜单项,直接放顶层是加不了√的.
jswac 2006-3-27 16:00
31
0
请教各位老大

0100874A   .  00000000      DD 00000000     ;这个位置是用来记录当前的状态的

就是这一行 DD 00000000 我在OD里面老是添加不成功,那位老大能给个解释
谢谢
黄连 2006-3-27 17:22
32
0
很详细呀,谢谢了!!
samsalt 2006-3-28 07:46
33
0
强人
收藏了,谢谢!
aptime 2006-3-29 14:44
34
0
en 很详细 辛苦了
qyc 4 2006-3-30 23:15
35
0
又是经典记事本PEDIY//学习
楼主窗口透明你怎用上了一个DLL啊//能给出原文来吗?
risk 2006-4-1 15:44
36
0
牛,学习~~~
xie7713 2006-4-2 16:16
37
0
谢谢了,收藏了。
luhouxiang 2006-4-6 20:59
38
0
其实若是多看看一些DIY EXE文件的文章,然后再动手实践一下,相信很快就能得到提高,而不仅仅是破解.
kkbing 3 2006-4-6 21:28
39
0
是值得我们菜鸟练手
游客
登录 | 注册 方可回帖
返回