-
-
[翻译]为程序添加闪屏
-
发表于:
2006-8-10 11:16
15944
-
欢迎回来,读了我的关于“在程序中插入对话框”文章后,很多人问我能不能在程序中插入一个启动画面(以下简称为闪屏)。
是的,这可以做到,你可以对PE文件注入任何东西,只要你的逆向水平够高。
事实上我正在考虑做这件事情,所以第一步就是考虑需要做些什么,让我们来想想需要做的所有步骤。
为什么插入一个闪屏就意味着需要做很多工作……
首先,需要创建一个窗口,有三种方法可以实现。
1、你可以增加一个对话框资源,然后呼叫DialogBoxParamA函数,问题是增加一个对话框资源没有那么简单,如果程序没有资源段你还得为它添加资源段,那就更难了。
2、添加代码,那意味着你不得不构造一个WNDCLASSEX结构,呼叫RegisterClassEx和Create WindowEx,并注入对话框循环代码。麻烦的是你必须注入大量的代码,而且需要在输入表中引入要用到的大量的API。
3、我认为最好的办法是在内存中添加对话框窗口(只要构造一个DLGTEMPLATE结构),并且呼叫CreateDialoglndirect。
另外,你还必须插入一个Windowproc/DialogProc回调函数代码(三个步骤都要),这就意味着需要做更多的工作(想想那些对话框的循环语句)。
我们的BMP图象又该怎样处理?第一个问题就是它应该存在哪里,这里也有几种方法:
1、将图象资源放入程序的资源段(就象处理对话框资源一样)。
2、不把它放入程序里面,所以你将有两个文件,一个是图象文件,一个PE文件。
3、更好的方法是,复制图象文件的所有字节到一个区段。
然后在文件中引入图象,并贴在一个窗口中,再设置一个计时器,让闪屏在定义的时间内关闭。
・搜索另一种方法
我在考虑另一种方法,使我们不用注入这么多代码。
我在网络上发现了“John Peloquin”写的一个非常好、非常有意思的代码叫做“远程注入补丁”,它是利用CreateProcess远程注入任何一个PE文件的补丁,在目标程序中申请内存空间利用WriteProcessMemory注入你需要的DLL文件,你可以自己看一下源码……
但是这种方法有两个顾虑:首先,我们现在有三个文件:PE文件、增加闪屏功能的DLL文件,还有个补丁;其次, CreateRemotoThread API函数只能适用于WinNT/2K/XP系统。
那是不是有不用补丁的方法呢?是的,我们只要写一个DLL文件,它包含闪屏图象,并将代码写入DLLMan函数中的DLL-PROCESS-ATTACH分支,然后在目标文件的输入表中添加这个DLL文件,需要用到DLL的输出功能。
・写DLL文件
下面是用C语言写的非常简单的一小段DLL代码……
#include <windows.h>
#include "resource.h"
#pragma comment(linker,"/ENTRY:DllMain") // 设置DllMain函数入口
extern "C" int Func1(); // 声明输出函数
extern "C" int Func1()
{
return 0;
}
BOOL DlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
DWORD TimerID;
switch(msg)
{
case WM_CLOSE:
{
KillTimer(hwnd, TimerID);
EndDialog(hwnd, 0);
}
break;
case WM_INITDIALOG:
{
TimerID = SetTimer(hwnd, 466, 3000, NULL);
}
break;
case WM_TIMER:
{
SendMessage(hwnd, WM_CLOSE,0,0);
}
break;
default:break; }
return FALSE;
}
// :: Dll EntryPoint
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason,LPVOID lpReserved)
{ switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
DialogBoxParamA(hModule, MAKEINTRESOURCE(101), NULL, (DLGPROC)DlgProc, NULL); }
break;
case DLL_PROCESS_DETACH:
{
}
break;
}
return TRUE;
}
[C用户注意: 不要忘记在源码文件目录下放置.def文件.否则在输出表中将看不到输出函数。代码应该是这样的:
LIBRARY
EXPORTS
Func1
]
确实是非常简单的DLL代码,不是吗?图象文件放在对话框窗口中存储到资源中,然后呼叫DialogBoxParam显示对话框窗口,计时器设置为3秒后进入真正的程序,有两点非常重要。
――DialogBoxParamA必须在DLLMain函数中的DLL-PROCESS-ATTACH分支中引用。当程序被加载时,DLL-PROCESS-ATTACH的值发送到DLL。这就是我们所需要的。
――DLL的输出函数我们命名为FuncI,这个函数没什么用,我们从来不去用它,但是它又是必须的因为这个DLL要求必须至少有一个输出函数。
好了,我希望大家都能清楚每个步骤,如果你不明白再看最后一步。
・最后一步
现在我们已经做好了我们需要的DLL,让我们看看如何为可执行文件添加闪屏功能,下面是为ProcessView添加闪屏的例子。
我们都很懒惰,不想手工添加DLL到输入表,所以我们可以用SantMat写的IIDKing来实现,打开IIDKing加载ProcessView,这个实例中,DII的名字是tutsplash.dll,输出函数是FuncI(建议用IIDKing2.01),选中后,按下添加按钮就可以了。
现在你运行程序就可以看到漂亮的闪屏了,Btw:非常重要的一点,目标文件和DLL文件一定要在同一个目录下。
我们所做的仅仅是舔加这个DLL到输入表。如果你运行程序,它将会连接输入表中所有的DLL文件。所以ProcessView现在也加载tutsplash.dll并自动发送DLL_PROCESS_ATTACH…
希望你能够理解相关的联系,知道它的工作原理。所以你现在可以很容易地为程序增加闪屏而不需要复杂的逆向工作。
文:SUNSHINE
译:laomms
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)