如何能修改已编译的exe文件使之调用当前目录下的dll? 现在有个编译好的exe文件,我想让它运行时能使用当前目录下的一个dll文件,不需要指定调用这个dll中的哪个函数,因为已经有脚本写好了,现在只需要让这个程序运行时同时运行那个dll就行。有什么方法能实现? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 暂停的方式创建进程, 创建远线程去Load Dll, 再恢复线程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;} 已经编译好的exe不修改的话是无论如何都不能调用你随便指定的一个dll的。你说的脚本写好了,写好了给谁用?要么修改代码重新编译这个exe,要么用另一个程序采用楼上类似的方法注入指定的dll。 简单一点的,你把要使用的DLL的路径写在配置文件里 使用PE注入技术。编写自定位代码装载DLL,将代码添加到新的节区里面先于原程序运行。你的代码在原程序的进程空间运行,不必远程注入了;不过,PE注入实现起来有点麻烦,需要对PE格式有比较详细的了解。还是远程注入吧,相比之下简单多了。 “DLLname\0”call nextnext: pop eax再通过eax减去dll名称长度以及call代码长度,得到dll名称首址push eaxcall LoadLibraryjmp 0x1234567 (远跳,得到入口后把这个地址用入口地址替换)将对应的代码写到数据段空的地方,修改数据段属性为可运行(实际不修改也可以)从PE中找到程序入口,把入口改到你的call next上 请问cstring类型的变量怎么构造成sql语句 动态IP怎么用VC远程调试啊? onsize函数问题 急急急!在线等待,datagrid,ADO data control控件使用时出现的怪事情..... MFC的位图道入问题 有关贝塞尔曲线的问题! 请教关于VC中的各种数据类型的说明 如何在CList控件上处理鼠标右键的消息? 那里有SSL3的书籍或文档下载? 开机进入win98时,自动加载运行程序,怎么实现更好? 最好的视频教程网站,有很多学科的视频教程下载,千万别错过了。 [ 考研RMB悬赏:-) ]哈工大滴同学请进~
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;
}
call next
next: pop eax
再通过eax减去dll名称长度以及call代码长度,得到dll名称首址
push eax
call LoadLibrary
jmp 0x1234567 (远跳,得到入口后把这个地址用入口地址替换)
将对应的代码写到数据段空的地方,修改数据段属性为可运行(实际不修改也可以)从PE中找到程序入口,把入口改到你的call next上