📄 artic.asm
字号:
;===============================================修改说明===============================================
【软件名称】XP记事本(Notepad)
【下载地址】附件(附本文)
【应用平台】Win9x/NT/2000/XP
【软件大小】70K
【软件限制】未修改时,不能使用背景色,文字色,下划线,删除线。
【保护方式】--------
【修 改 者】andy00
【修改难度】1/10
【修改说明】只是为了熟悉逆向工程,所以使用静态分析。
【分析工具】Olldbg,计算器
【参考资料】MSDN
【软件简介】--------
;===============================================增加的功能分析=========================================
功能1 使字体对话框显示颜色,下划线,删除线的选项
功能2 在"查看"菜单下添加"背景色"菜单,点击能够选择颜色
功能3 让编辑框使用文字颜色,文字下划线,文字删除线,背景颜色功能
;==========================================步骤1 增加数据与代码区段===================================
用OLLDBG查看数据段,估计数据段的空闲字节数能够保存修改后生成的所有数据,此处选择从AE00到结束的空间来保存要用到的变量.添加代码需要比较大的空间,因此添加一个可执行区段(既然为了熟悉PE结构就手工添加),添加后在LordPE中验证添加成功:
SecName VOffset VSize ROffset RSize Flags
andy00 13000 1000 10400 1000 E0000020
因此新加代码放到:13000-10400 (RVA)
新加变量放到:0AE00-0AFFC (RVA)
;=========================================步骤2 需增加的变量与代码分析==================================
;功能1 使字体对话框显示颜色,下划线,删除线的选项
记事本使用API函数ChooseFont打开字体对话框,此函数只有一个参数,指向CHOOSEFONT结构体的指针,CHOOSEFONT结构体定义如下
typedef struct {
DWORD lStructSize;
HWND hwndOwner;
HDC hDC;
LPLOGFONT lpLogFont;
INT iPointSize;
DWORD Flags;
COLORREF rgbColors;
LPARAM lCustData;
LPCFHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
HINSTANCE hInstance;
LPTSTR lpszStyle;
WORD nFontType;
INT nSizeMin;
INT nSizeMax;
} CHOOSEFONT, *LPCHOOSEFONT;
成员说明:
rgbColors 用来保存用户选择的文字颜色
Flags 用来初始化字体对话框的各选项
因此:
1 将用户选择的颜色rgbColors保存起来,放到AF94 设为DWORD(COLOREF) crText
2 记事本打开字体对话框时默认没有颜色的,下划线,删除线选项.要增加这些选项.只需要将Flags|CF_EFFECT,其中CF_EFFECT==0x100
;功能2 在"查看"菜单下添加"背景色"菜单,点击能够选择颜色
直接用ResHack在"查看"菜单下添加一个菜单项"背景色(&B)",ID为1C
点击菜单打开对话框,需要处理WM_COMMAND消息,并在消息在调用API函数ChooseColor().WM_COMMAND消息定义如下
WM_COMMAND (==111)
WPARAM wParam
LPARAM lParam;
参数说明:
wParam 对于菜单,低字代表菜单ID,高字为0
lParam 对于菜单,为0
API函数ChooseColor打开颜色选择对话框,此函数只有一个参数,指向CHOOSECOLOR结构的指针其中CHOOSECOLOR结构定义如下
typedef struct {
DWORD lStructSize; //+0
HWND hwndOwner; //+4
HWND hInstance; //+8
COLORREF rgbResult; //+C
COLORREF *lpCustColors; //+10
DWORD Flags; //+14
LPARAM lCustData; //+18
LPCCHOOKPROC lpfnHook; //+1C
LPCTSTR lpTemplateName; //+20
} CHOOSECOLOR, *LPCHOOSECOLOR;
1 结构体长度为24,选用空间AFA0-AFC0存放此结构,设为 CHOOSECOLOR cc
2 此结构的一个成员lpCustColors指向一个COLORREF数组,此处用AE00开始的空间保存,设为 COLORREF crCustomColor[10]
3 还需要一个变量用来保存用户选择的颜色,此处用AF98保存,设为 COLORREF crBkgnd;
;功能3 将选择的字体颜色和背景颜色应用到编辑框上面
设置文字颜色和背景颜色需要处理编辑框的WM_CTLCOLOREDIT消息,消息定义如下:
WM_CTLCOLOREDIT (==133)
WPARAM wParam
LPARAM lParam;
参数说明
wParam 编辑框的设备内容句柄.
lParam 编辑框的窗口句柄
每个非Disable和非ReadOnly的编辑框都可以发送这个消息,但是因为这里只有一个编辑框,所以不需要判断.直接在消息中调用
SetTextColor(wParam,crText) ;设置文字颜色
SetBkColor (wParam,crBkgnd) ;设置背景颜色
此处需要一个画刷,颜色与背景色相同,返回给父窗口用来刷背景.将此画刷在AF9C,设为HBRUSH hBrBkgnd
;=========================================步骤3 功能实现伪代码====================================
HWND hEdit; ;编辑框句柄,原程序中肯定已保存,因此暂不分配空间
COLORREF crCustomColor[10]; ;AE00
COLORREF crText; ;AF94
CHOOSECOLOR cc; ;AFA0-AFC0
COLORREF crBkgnd; ;AF98
HBRUSH hBrBkgnd; ;AF9C
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND: //WM_COMMAND=111
switch (LOWORD(wParam))
{
case IDM_EDIT_CHOOSEFONT: //"字体"菜单
......
CHOOSEFONT.Flags|=CF_EFFECT; //增加颜色,下划线,删除线选项
//..ChooseFont()
crText=CHOOSEFONT.rgbColor; //保存选择的颜色
break;
case IDM_VIEW_CHOOSECOLOR: //IDM_VIEW_CHOOSECOLOR==1C "背景色"菜单
cc.lStructSize =sizeof(cc); //+0
cc.hwndOwner =hEdit; //+4
cc.hInstance =0; //+8
cc.rgbResult =0x00ff00; //+C
cc.lpCustColors =crCustom; //+10
cc.Flags =CF_RGBINIT; //+14
cc.lCustData =0; //+18
cc.lpfnHook =0; //+1C
cc.lpTemplateName =0; //+20
if(ChooseColor(&cc)==TRUE)
{
DeleteObject(hBrBkgnd); //删除以前创建的,以免内存泄露
clBkgnd=cc.rgbResult; //保存背景色
hBrBkgnd=CreateSolidBrush(clBkgnd); //根据选择的颜色创建画刷
InvalidateRect(hEdit,NULL,TRUE); //强制更新
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CTLCOLOREDIT:
SetTextColor((HDC)wParam,clText); //设置文字色
SetBkColor((HDC)wParam,clBkgnd); //设置背景色
return (LRESULT)hBrBkgnd; //返回画刷
case WM_DESTROY:
DeleteObject(hBrBkgnd); //删除GDI对象,避免内存泄露
//....
PostQuitMessage(0); //原有代码,退出程序
break;
//case .......
//case .......
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
;=========================================步骤4 增加输入函数======================================
从步骤2,3分析可知,需要用到的API函数
ChooseColorW
CreateSolidBrush
SetTextColor
SetBkColor
DeleteObject
InvalidateRect
用LordPE查看记事本的输入表,已输入的函数:
DllName FunName(函数名) ThunkRVA(调用偏移)
gdi32.dll DeleteObject 1224
gdi32.dll InvalidateRect 1068
输入其余函数(本来用手动输入,但是调用的时候总有问题,因此用LordPE输入)
DllName FunName(函数名) ThunkRVA(调用偏移)
comdlg32.dll ChooseColorW 1401C
gdi32.dll CreateSolidBrush 1405D
gdi32.dll SetTextColor 14061
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -