⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 artic.asm

📁 一个增加记事本软件功能的教程
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;===============================================修改说明===============================================

【软件名称】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 + -