能力值:
( LV2,RANK:10 )
|
-
-
2 楼
重定位信息 。。。。。。。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
改他PE头....
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
楼上各位,本人愚钝,能否详细指点?
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
1. exe一般是没重定位信息的, 这种情况你必须保留他使用的地址给他用, 否则会异常
2. exe作为dll 加载进去, 很多东西是没经过初始化的(全局对象, crt库初始化 ....)
修改另外那个exe的基址 再编译 试试看
|
能力值:
( LV3,RANK:20 )
|
-
-
6 楼
给LZ推荐一个贴子http://bbs.pediy.com/showthread.php?t=113450 如果解决了你的问题,请帮他顶一下!!呵呵。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
5楼说的对,EXE做为DLL使用时,代码没有初始化,因此,当函数中如果只是简单的运算则可以被外部过程正常调用,而在函数中使用系统的API或资源时,则会因没有重定位信息不能正常运行。
这正是我询求大家解决的问题
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
借用6楼提供帖子中的论述方法,对我的问题重新描述:
程序HH.EXE可独立运行,内有很多导出函数。
程序CC.EXE也可独立运行。我希望CC可以使用HH的导出函数。
但是HH做为DLL使用时,由于它是EXE文件,因此我没有办法将它象对待其它DLL程序那样正确初始化。
说的更具体一些就是EXE文件做DLL使用时如何对它做初始化
请高人想想办法!此问题很有挑战性!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
exe的入口函数书WinMain,
DLL的的入口函数是DllMain
你在HH.EXE中增加一个DllMian函数来做初始化工作。
不知道这样行不行。
|
能力值:
( LV12,RANK:250 )
|
-
-
10 楼
在贴子http://bbs.pediy.com/showthread.php?t=113450的基础上,
修改后CC的一些导入库可能存在一些问题,会出现无法加载的情况。而且内部如果使用了HH的硬地址等,就无法独立运行了。
如果你需要做初始化,建议你在修改PE入口时,LoadLibrary前,先调用初始化代码,或许可以解决你的问题。
修改后可以使用API及系统资源,至于能不能使用窗口函数什么的,不大确定。
只不过调用的初始化代码不能是原先的入口了,而且现在IDE做出来的EXE,入口代码都是由编译器生成的,也的确做了一堆环境初始化工作,再调用main函数。结束后释放资源,调用ExitProcess。
既然CC、HH是你自己做的,那不如就把代码改造成DLL重新编译一遍呗,何必自找麻烦哩。初始化的确是件麻烦事。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
To iicup :
按你的方法做了,可能是我实现的过程不对,没有成功。
To triones :
CC、HH是自己做的,但我想让它们相互依存,如果它们之间少了另一半则功能上也会少很多。想有“1+1>2”的效果。如果做成公共DLL则没有相互依存的关系,功能上也固定了,只能是"1+1=2"
|
能力值:
( LV12,RANK:250 )
|
-
-
12 楼
那不如就做成plugin.dll喽
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
有这面的目的,但plugin.dll是DLL,它必须依附与其它的EXE或DLL。
我希望HH.exe和CC.exe本身相对独立的,能够完成各自的功能。如果它们在一起时,就都具有plugin.dll作用,互为补充。
这只是设计上的想法,真的有点BT
|
能力值:
( LV12,RANK:250 )
|
-
-
14 楼
要不就让它们分别独立运行,然后开放通讯,依靠通讯完成相互功能。
否则,两个EXE之间的相互利用,难。
|
能力值:
( LV13,RANK:970 )
|
-
-
15 楼
这个原理还是很简单的,把目标exe可以随便加载,比如读文件,或者干脆LoadLibrary就可以了。然后搜索其导入表,都修改成正确的指针就行了。然后再修改exe内需要重定位的地址,这个也不麻烦的。
修正重定位表的代码大概如下:
hMod = LoadLibrary("aa.exe");
if (!hMod)
return false;
pDosHeader = (PIMAGE_DOS_HEADER)hMod;
pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);
bRet = TRUE;
while(pImportDescriptor->FirstThunk)
{
//获取dll名称
char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);
pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk);
int no = 1;
while(pThunkData->u1.Function)
{
if ((pThunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG)
{
//获取函数名称
funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2);
if (!GetModuleHandle(dllname))
{
LoadLibrary(dllname);
}
myaddr = (int*)GetProcAddress(GetModuleHandle(dllname), funname);
}
PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) +(no-1);
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(lpAddr,&mbi,sizeof(mbi));
VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
if (WriteProcessMemory(GetCurrentProcess(), lpAddr, &myaddr, sizeof(DWORD), NULL) == FALSE)
{
bRet = FALSE;
break;
}
VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
no++;
pThunkData++;
}
pImportDescriptor++;
}
修正需要重定位的地址和数据:
for (int i = 0; i < xxx; i++)
{
lpAddr = (PDWORD)(RelocAll[i] + (DWORD)hMod);
VirtualQuery(lpAddr,&mbi,sizeof(mbi));
VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
ReadProcessMemory(hProcess, (LPCVOID)lpAddr, &dwOrg, sizeof(DWORD), &dwRetCount);
dwOrg = dwOrg - 0x400000;
dwOrg = dwOrg + (DWORD)hMod;
if (WriteProcessMemory(hProcess, (void*)lpAddr, &dwOrg, sizeof(DWORD), NULL) == 0)
bRet = false;
}
|
能力值:
( LV13,RANK:970 )
|
-
-
16 楼
我在这个帖子里发的附件,就是一个exe加载另外一个exe,然后直接在自己镜像内把那个exe跑起来了,不过被人说成简单一毛的东西,我也懒得说什么了。
http://bbs.pediy.com/showthread.php?t=99799
|
能力值:
( LV9,RANK:200 )
|
-
-
17 楼
这个exe是自己的,那么编译的时候生成重定位目录不就ok了吗
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
不光是重定位的问题,还有DLL初始化的问题
EXE和DLL的初始化代码都是由编译器加进去的
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
非常感谢大家的回复!
To nbw :
看了你的代码,我想后面这段用于修改EXE导出表的,这种修改是否是在内存中进行的?如果是这样那它就是动态修改了。其基址0x400000可视具体情况进行改变,基址的确定是否需根据主调程序的基址确定还是根据做为DLL使用的EXE的基址确定?
你的思路我理解为,HH.exe做为HH.dll使用时,需在 LoadLibrary("HH.exe");后修改重定位表,然后再取各导出函数的地址或名柄,最后调用。不知这样理解对不??
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
To 16楼
如果在一个CC.exe中让另一个HH.exe运行起来是一回事,而让CC.exe使用HH.exe中的函数则是另一回事。
可能是网友理解的产一样。
|
能力值:
( LV13,RANK:970 )
|
-
-
21 楼
第一句话问的那三个问号太长了,我看不过来,也不知道对不对。第二个句子理解的是对的。修改导入表这个很简单的。麻烦的是处理需要重定位的别的一些地址,比如hh.exe里原来可能有个这:
push 0x401234,而这个0x401234地方指向一个字符串。这时候你就要修正这个立即数了,让他指向正确的内存位置,这个就有点麻烦了。
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
是这样?......。那么在HH.exe中就少用或不用立即数,非用不可的地方用常量。这查以在程序设计中达到。不知其它的地方还有那些需要注意的?
重复20楼的内容: 修改EXE导出表是在 LoadLibrary("HH.exe")后之后进行,也就是调入内存后进行修改? 如果是这样那它就是动态修改了。
修改时,其基址0x400000可视具体情况进行改变,基址的确定是根据主调程序的基址确定还是根据做为DLL使用的EXE的基址确定?
|
能力值:
( LV13,RANK:970 )
|
-
-
23 楼
当然是根据做为DLL使用的EXE的基址确定。不好意思很绕口的问题我一般大脑自动过滤很严重
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
To nbw:
谢谢你的帮助!
也谢谢大家!的支持.
由于最近有点忙,对这个问题的深入学习和研究可能要待很长时间.慢慢学习,慢慢提高!
|
能力值:
( LV3,RANK:20 )
|
-
-
25 楼
与LZ握个手,之前也这么想过,用VS2003编写,不过当时觉得手工初始化dll太麻烦了,后来就扔到一边了。
当时弄出来的结果就是同一个文件,用LordPE打开修改特征值为010E就是exe,修改为210F就是dll。不过由于exe和dll的原始入口原型不同,还需要进行一些处理。exe的是int WinMainCRTStartup(void),dll的是BOOL WINAPI _DllMainCRTStartup(HANDLE, DWORD, LPVOID),如果要两者共存于一个文件,可以自己指定程序入口,用VirtualQuery取自身模块基址和GetModuleHandle取exe基址判断是否相等来确定当前是exe还是dll,然后再调用相应的原始入口并小心平衡堆栈即可,此外C/C++运行库要选择MD方式,否则wincrt0.obj和dllcrt0.obj有部分函数冲突,貌似无法解决。
|
|
|