您的位置:程序门 -> vc/mfc -> 进程/线程/dll



如何能修改已编译的exe文件使之调用当前目录下的dll?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


如何能修改已编译的exe文件使之调用当前目录下的dll?
发表于:2007-10-09 22:53:19 楼主
现在有个编译好的exe文件,我想让它运行时能使用当前目录下的一个dll文件,不需要指定调用这个dll中的哪个函数,因为已经有脚本写好了,现在只需要让这个程序运行时同时运行那个dll就行。有什么方法能实现?
发表于:2007-10-10 00:34:021楼 得分:0
暂停的方式创建进程,   创建远线程去load   dll,   再恢复线程
c/c++ code
bool runwithdll(char * pruncmd, char * pdllpath) { char * pcmd = null; char * pcurdir = null; bool bpart = false; char szcurdir[1024]; dword dwlen; dword i; while*pruncmd == ' ') pruncmd++; dwlen = (dword)strlen(pruncmd); for(i=0; i<dwlen; i++) { if(pruncmd[i] == ' ' && bpart == false) { pcmd = pruncmd + i; break; } if(pruncmd[i] == '"') { if(bpart) bpart = false; else bpart = true; } } if(pcmd == null) { pcmd = pruncmd; } for(; i>0; i--) { if(pruncmd[i] == '\\') { memset(szcurdir, 0, sizeof(szcurdir)); if(pruncmd[0] == '"') { strncpy(szcurdir, pruncmd+1, i-1); szcurdir[i-1] = 0; } else { strncpy(szcurdir, pruncmd , i ); szcurdir[i] = 0; } pcurdir = szcurdir; break; } } // msga("pcmd:%s\r\npcurdir:%s", pcmd, pcurdir); process_information processinfo; startupinfoa startupinfo; zeromemory(&startupinfo, sizeof(startupinfo)); startupinfo.cb = sizeof(startupinfo); //only compulsory field startupinfo.wshowwindow = sw_show; //windows media player not show startupinfo.dwflags = startf_useshowwindow; if(createprocessa(null, pruncmd, null, null, false, create_suspended, null, pcurdir, &startupinfo, &processinfo) == false) { return false; } if(procremtloaddll(processinfo.hprocess, pdllpath) == false) { ::resumethread(processinfo.hthread); closehandle(processinfo.hthread); closehandle(processinfo.hprocess); return false; } ::resumethread(processinfo.hthread); //create_suspended for wait the dll load done closehandle(processinfo.hthread); closehandle(processinfo.hprocess); return true; } hmodule procremtloaddll(handle hproc, char * pdllpath) { byte code[0x20]; //00 hmodule hmodule; //20 int nerror; //24 //28 :pdllpath dword dwsize = 0x20+4+4+1024, dwnedsize; char * plibstr; bool bret; fun1 pfunloadlib; handle thd_hd; pfunloadlib = (fun1)::getprocaddress(::getmodulehandle(_t("kernel32")), "loadlibrarya"); if(pfunloadlib == null) return null; plibstr =char *)virtualallocex(hproc, 0, dwsize, mem_commit, page_EXECute_readwrite); if(plibstr == null) return null; createthreadfun1(code, (dword)plibstr, (dword)pfunloadlib, (lpdword)(plibstr+0x20), (lpdword)(plibstr+0x24)); dwnedsize = 0x20; bret = writeprocessmemory(hproc, plibstr, code, dwnedsize, &dwsize); //复制代码 if(bret == false || dwsize != dwnedsize ) { virtualfreeex(hproc, plibstr, 0, mem_release ); return null; } dwnedsize = (dword)strlen(pdllpath) + 1; bret = writeprocessmemory(hproc, plibstr+0x28, pdllpath, dwnedsize, &dwsize); //复制参数 if(bret == false || dwsize != dwnedsize ) { virtualfreeex(hproc, plibstr, 0, mem_release ); return null; } thd_hd = ::createremotethread(hproc, 0, 0, (lpthread_start_routine)plibstr, (void *)(plibstr+0x28), null, null); if(thd_hd == null) { virtualfreeex(hproc, plibstr, 0, mem_release); return null; } waitforsingleobject(thd_hd,infinite); closehandle(thd_hd); dwnedsize = 4; bret = ::readprocessmemory(hproc, plibstr+0x20, &hmodule, dwnedsize, &dwsize); if(bret == false || dwsize != dwnedsize ) { virtualfreeex(hproc, plibstr, 0, mem_release); return null; } if(hmodule == null) { bret = ::readprocessmemory(hproc, plibstr+0x24, &nerror , dwnedsize, &dwsize); if(bret == false || dwsize != dwnedsize ) { virtualfreeex(hproc, plibstr, 0, mem_release); return null; } ::setlasterror(nerror); } bret = virtualfreeex(hproc, plibstr, 0, mem_release); if(bret == false) return null; return hmodule; } lpbyte createthreadfun1(lpbyte pcode, dword dwcodeadr, dword dwcallfunadr, lpdword pfunretval, lpdword perror) { dword dwfunerror; dwfunerror = (dword)&getlasterror; *(dword *)(pcode + 0x00) = 0x042474ff; //push d,[esp+04] *( byte *)(pcode + 0x04) = 0xe8; //call *(dword *)(pcode + 0x05) = dwcallfunadr - (4+5); // fun相对地址 *(dword *)(pcode + 0x05) = dwcallfunadr - (dwcodeadr+0x04+5);// dwcallfunadr相对地址 *( byte *)(pcode + 0x09) = 0xa3; //mov [ ],eax *(dword *)(pcode + 0x0a) = (dword)pfunretval; // funretval *( byte *)(pcode + 0x0e) = 0xe8; //call *(dword *)(pcode + 0x0f) = dwfunerror - (dwcodeadr+0x0e+5);// getlasterror相对地址 *( byte *)(pcode + 0x13) = 0xa3; //mov [ ],eax *(dword *)(pcode + 0x14) = (dword)perror; // perror *( byte *)(pcode + 0x18) = 0xc2; //retn *( word *)(pcode + 0x19) = 0x0004; // 04 //一个参数返回 *( word *)(pcode + 0x1b) = 0xcc; //int 3 return pcode; }
发表于:2007-10-10 06:01:032楼 得分:0
已经编译好的exe不修改的话是无论如何都不能调用你随便指定的一个dll的。你说的脚本写好了,写好了给谁用?

要么修改代码重新编译这个exe,要么用另一个程序采用楼上类似的方法注入指定的dll。
发表于:2007-10-10 08:15:383楼 得分:0
简单一点的,你把要使用的dll的路径写在配置文件里
发表于:2007-10-10 08:36:544楼 得分:0
动态加载你配置文件写的dll
发表于:2007-10-10 10:11:035楼 得分:0
反汇编,手动加汇编代码
发表于:2007-10-10 10:29:236楼 得分:0
上面的远程注入怎么那么复杂...我晕~
发表于:2007-10-10 23:06:537楼 得分:0
使用pe注入技术。编写自定位代码装载dll,将代码添加到新的节区里面先于原程序运行。

你的代码在原程序的进程空间运行,不必远程注入了;不过,pe注入实现起来有点麻烦,需要对pe格式有比较详细的了解。

还是远程注入吧,相比之下简单多了。
发表于:2007-10-15 01:18:258楼 得分:0
“dllname\0”
call   next
next:   pop   eax
再通过eax减去dll名称长度以及call代码长度,得到dll名称首址
push   eax
call   loadlibrary
jmp     0x1234567   (远跳,得到入口后把这个地址用入口地址替换)
将对应的代码写到数据段空的地方,修改数据段属性为可运行(实际不修改也可以)

从pe中找到程序入口,把入口改到你的call   next上


快速检索

最新资讯
热门点击