【文章标题】: 给记事本加上透明窗体功能-入门级的东东
【文章作者】: sLtYJ[D.4s][DFCG][BCG](4stone)
【作者邮箱】: sltyjycg@163.com
【作者主页】: 挂了
【作者QQ号】: 删了
【软件名称】: 系统自带记事本
【软件大小】: 67.5KB
【下载地址】: X:\windows\notepad.exe
【加壳方式】: 无壳
【保护方式】: 无
【编写语言】: Microsoft Visual C++ 7.0
【使用工具】: OD,LordPE,ResHacker
【操作平台】: XP-Sp2_EN
【软件介绍】: 系统自带记事本,小巧实用.
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
在论坛混了这么久,没写过什么文章..惭愧惭愧.今天凑合着写一篇,也算是对自己有个交代.
进入正题吧,看着许多牛人通过逆向对记事本加了许多形形色色的功能(背景色,TOP,工具栏等等),看来记事本还是比较好欺负的,呵呵.今天我们就再来给他加个窗体透明的功能.
窗体透明需要用到的几个函数:
LONG GetWindowLong(
HWND hWnd, // handle to window
int nIndex // offset of value to retrieve
);
LONG SetWindowLong(
HWND hWnd, // handle to window
int nIndex, // offset of value to set
LONG dwNewLong // new value
);
BOOL SetLayeredWindowAttributes(
HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
);
用LordPE查看后发现程序里没有我们需要的函数,所以先添加API(否则无法跨平台),这些都在USER32.DLL里.
然后我们用ResHacker在菜单项里添加一个新的菜单:
POPUP "&View"
{
MENUITEM "&Status Bar", 27
MENUITEM "&Transparence", 118
}
OK,完成上述工作后我们就可以用OD载入进行DIY工作了...为了省事,直接参考前辈们的文章,Ctrl+G来到
01002BBE |. 83FF 40 CMP EDI,40 ; 这里开始比较控件/菜单ID了,
01002BC1 |. 8995 F0FDFFFF MOV DWORD PTR SS:[EBP-210],EDX ; 所以更改此处跳到自己的代码
01002BC7 |. 0F8F F9060000 JG Notepad.010032C6 ; 自己的代码最后必须跳回此处
01002BCD |. 0F84 DB060000 JE Notepad.010032AE
01002BD3 |. 83FF 15 CMP EDI,15
01002BD6 |. 0F8F CE020000 JG Notepad.01002EAA
01002BDC |. 0F84 EC030000 JE Notepad.01002FCE
因为我们需要实现的功能代码比较少,所以直接在程序中找空地,1008747很适合我们...OK,更改上述代码为:
01002BBE . /E9 845B0000 JMP Notepad.01008747 ; 跳到自己的代码处
01002BC3 |90 NOP
01002BC4 |90 NOP
01002BC5 |90 NOP
01002BC6 |90 NOP
01008747 > \83FF 76 CMP EDI,76 ; 比较控件ID号
0100874A . 75 2C JNZ SHORT Notepad.01008778 ; 不是我们的就跳走
0100874C . 6A EC PUSH -14 ; /Index = GWL_EXSTYLE
0100874E . 36:FF35 30980>PUSH DWORD PTR SS:[1009830] ; |hWnd = NULL ;窗体句柄,稍候讲解如何获取
01008755 . 36:FF15 7A400>CALL DWORD PTR SS:[<&user32.GetWindowLon>; \GetWindowLongA ;获取窗体当前的Style
0100875C . 3D 10010000 CMP EAX,110 ; 比较是否已经被透明化过
01008761 . 74 23 JE SHORT Notepad.01008786 ; 没有透明化,则跳..进行透明化
01008763 . 25 FFFFF7FF AND EAX,FFF7FFFF ; 进行还原透明化工作,还原EAX的值为110
01008768 . 50 PUSH EAX ; /NewValue
01008769 . 6A EC PUSH -14 ; |Index = GWL_EXSTYLE
0100876B . FF35 30980001 PUSH DWORD PTR DS:[1009830] ; |hWnd = NULL
01008771 . 90 NOP ; |
01008772 . FF15 7E400101 CALL DWORD PTR DS:[<&user32.SetWindowLon>; \SetWindowLongA ;还原Style
01008778 > 83FF 40 CMP EDI,40 ; 这里是程序原来的代码,我们补上.
0100877B . 8995 F0FDFFFF MOV DWORD PTR SS:[EBP-210],EDX ; 同上
01008781 .^ E9 41A4FFFF JMP Notepad.01002BC7 ; 跳会原程序代码继续执行
01008786 > 0D 00000800 OR EAX,80000 ; 为窗体加上WS_EX_LAYERED属性
0100878B . 50 PUSH EAX ; /NewValue
0100878C . 6A EC PUSH -14 ; |Index = GWL_EXSTYLE
0100878E . 36:FF35 30980>PUSH DWORD PTR SS:[1009830] ; |hWnd = NULL
01008795 . 36:FF15 7E400>CALL DWORD PTR SS:[<&user32.SetWindowLon>; \SetWindowLongA ;设置窗体Style
0100879C . 6A 02 PUSH 2 ; LWA_ALPHA = 2h
0100879E . 68 C8000000 PUSH 0C8 ; 透明程序
010087A3 . 6A 00 PUSH 0
010087A5 . FF35 30980001 PUSH DWORD PTR DS:[1009830]
010087AB . 36:FF15 82400>CALL DWORD PTR SS:[<&user32.SetLayeredWi>; USER32.SetLayeredWindowAttributes ;透明吧..
010087B2 .^ EB C4 JMP SHORT Notepad.01008778 ; 跳到程01008778执行程序原来的代码
好了,至此我们的DIY工作已经告一段落了..下面补充讲解一下如何获取窗体的句柄([1009830])
载入OD后下断bp CreateWindowExW 返回后我们来到如下代码:
01004667 |. 53 PUSH EBX ; /lParam
01004668 |. 56 PUSH ESI ; |hInst
01004669 |. 53 PUSH EBX ; |hMenu
0100466A |. 53 PUSH EBX ; |hParent
0100466B |. FF35 709A0001 PUSH DWORD PTR DS:[1009A70] ; |Height = 272 (626.)
01004671 |. BE 94130001 MOV ESI,Notepad.01001394 ; |
01004676 |. FF35 749A0001 PUSH DWORD PTR DS:[1009A74] ; |Width = 393 (915.)
0100467C |. FF35 7C9A0001 PUSH DWORD PTR DS:[1009A7C] ; |Y = 3C (60.)
01004682 |. FF35 789A0001 PUSH DWORD PTR DS:[1009A78] ; |X = 11A (282.)
01004688 |. 68 0000CF00 PUSH 0CF0000 ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
0100468D |. 56 PUSH ESI ; |WindowName => ""
0100468E |. 68 20900001 PUSH Notepad.01009020 ; |Class = "Notepad"
01004693 |. 53 PUSH EBX ; |ExtStyle
01004694 |. FF15 E0110001 CALL DWORD PTR DS:[<&USER32.CreateWindow>; \CreateWindowExW
0100469A |. 8BD0 MOV EDX,EAX ; 返回句柄存放于EAX,传递给EDX
0100469C |. 3BD3 CMP EDX,EBX
0100469E |. 8915 30980001 MOV DWORD PTR DS:[1009830],EDX ; 将EDX句柄存入DWORD PTR DS:[1009830]
010046A4 |. 8915 A4A40001 MOV DWORD PTR DS:[100A4A4],EDX
So....DWORD PTR DS:[1009830]就是我们要的窗体句柄.
好了..大家应该都看明白了吧..
--------------------------------------------------------------------------------
【经验总结】
呵呵 很久没写破问了,都生疏了~写得不好还请大家见谅.
参考文章:http://bbs.pediy.com/showthread.php?threadid=23277 |