VC:执行远程线程注入的代码段导致目标进程崩溃

以前也曾多次提到远程线程注入导致进程崩溃的现象。

此次崩溃不同于前几次。

之前,采用的是dll注入的方式,注入后,由于同一个dll文件在不同的进程中映射的基地址不同,导致远程线程函数的入口地址不同,以至崩溃,这种情况,多数是本进程采用静态链接加载待远程注入的dll文件,而其他进程则动态加载该dll文件,两次加载将在内存中产生两个dll实例。

此次,需要向远程进程注入代码段,远程线程函数入口地址正确。测试时,为了方便,特地增加了一个消息框MessageBox,远程线程函数仅仅调用这个弹出消息框的函数,然后退出。结果,消息框正常弹出,但是,当点击确定退出消息框后,目标进程立即崩溃。原因不明。

 

200807210756注:

实在不知道问题出哪儿了,于是就想看看注入的VC代码对应的反汇编代码,这时,忽然想到一点,即:我都是在Debug模式下执行的,这可能会有问题。

进一步思考。Debug版本和Release版本最大的不同在于,每次调用一个函数后,Debug版本会进行堆栈检测。而目标进程显然是处于release模式,此时,如果注入的是Debug版本的代码,那么,调用函数之后,会有一句检测堆栈的机器指令,这很可能就是进程崩溃的原因所在。

于是,改为release环境测试,一切正常!OK!

 

(我用控制台程序实现时没有问题,用MFC程序实现就有问题,因此发现以上内容,将Debug版改为Release版就没问题了)

另附上远程注入的主要代码段,供参考,有问题望指教!!!

 

#include "windows.h"
#include <string.h>
#include "stdio.h"
#include "Shlwapi.h"
#include "tlhelp32.h"
#include "Psapi.h"
#include   <TChar.h>
#pragma comment(lib,"Psapi.lib")
#pragma comment(lib,"Shlwapi.lib")

//参数结构 ;
typedef struct _RemotePara{
 DWORD dwExitProcessFunc;
}RemotePara;

// 远程线程执行体
DWORD __stdcall ThreadProc(RemotePara *Para){
 typedef void (__stdcall *pExitProcess) ( UINT );
 pExitProcess ExitProcessFunc = (pExitProcess)Para->dwExitProcessFunc;
 ExitProcessFunc(0);
 return 0 ;
}

BOOL EnablePrivilege(HANDLE hToken,LPCTSTR szPrivName,BOOL fEnable)
{
 TOKEN_PRIVILEGES tp;
 tp.PrivilegeCount = 1;
 LookupPrivilegeValue(NULL,szPrivName,&tp.Privileges[0].Luid);
 tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED:0;
 AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
 return((GetLastError() == ERROR_SUCCESS));
}

DWORD GetPidByName(char *szName)
{
 HANDLE hProcessSnap = INVALID_HANDLE_VALUE;
 PROCESSENTRY32 pe32={0};
 DWORD dwRet=0;

 hProcessSnap =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if(hProcessSnap == INVALID_HANDLE_VALUE)
  return 0;

 pe32.dwSize = sizeof(PROCESSENTRY32);
 if(Process32First(hProcessSnap, &pe32))
 {
  do
  {
   if(StrCmpNI(szName,pe32.szExeFile,strlen(szName))==0)
   {
    dwRet=pe32.th32ProcessID;
    break;
   }
  }while (Process32Next(hProcessSnap,&pe32));
 }
 else
  return 0;

 if(hProcessSnap != INVALID_HANDLE_VALUE)
  CloseHandle(hProcessSnap);
 return dwRet;
}

int main()
{
// DeleteFile("D://BioFileLogOp.dll");
 const DWORD THREADSIZE=1024*4;
 DWORD pID;
 DWORD byte_write;
 HANDLE hToken,hRemoteProcess,hThread;
 RemotePara myRemotePara,*pRemotePara;
 void *pRemoteThread;
 HINSTANCE hUser32 ;

 char szSafePath[MAX_PATH] = {"C://Program Files//Safe Office//oem//BioFileLogOp.dll"};
 char szKxPath[MAX_PATH] = {"C://Program Files//KeXin WPS Office//oem//BioFileLogOp.dll"};

 HANDLE hSafeFind;
 HANDLE hKxFind;
 WIN32_FIND_DATA   FindFileData,FindKxFileData;

 OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken); //打开进程

 EnablePrivilege(hToken,SE_DEBUG_NAME,TRUE); //提升为调试权限

 // 获得指定进程句柄,并设其权限为PROCESS_ALL_ACCESS

 pID = GetPidByName("KxIdentifyServer.exe");
 if(pID == 0)
 {
      return 0;
 }
 hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID);
 if(!hRemoteProcess)
  return 0;

 // 在远程进程地址空间分配虚拟内存
 pRemoteThread = VirtualAllocEx(hRemoteProcess, 0, THREADSIZE, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
 if(!pRemoteThread)
  return 0;

 // 将线程执行体ThreadProc写入远程进程
 if(!WriteProcessMemory(hRemoteProcess, pRemoteThread, &ThreadProc, THREADSIZE,0))
  return 0;
 ZeroMemory(&myRemotePara,sizeof(RemotePara));
 hUser32 = LoadLibrary("kernel32.dll");
 myRemotePara.dwExitProcessFunc = (DWORD)GetProcAddress(hUser32, "ExitProcess");

 //写进目标进程
 pRemotePara =(RemotePara *)VirtualAllocEx (hRemoteProcess ,0,sizeof(RemotePara),MEM_COMMIT,PAGE_READWRITE);
 if(!pRemotePara)
  return 0;
 if(!WriteProcessMemory (hRemoteProcess ,pRemotePara,&myRemotePara,sizeof myRemotePara,0))
  return 0;

 // 启动线程
 hThread = CreateRemoteThread(hRemoteProcess ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,pRemotePara,0,&byte_write);
 FreeLibrary(hUser32);
 CloseHandle(hRemoteProcess);
 CloseHandle(hToken);

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
进程注入自己的dll 带有测试dll 路径和要注入的程序可以自己改 hRemoteProcess=OpenProcess(PROCESS_CREATE_THREAD| //允许远程创建线程 PROCESS_VM_OPERATION | //VM操作 PROCESS_VM_WRITE , //允许写 FALSE,dwProcessID); if(!hRemoteProcess) AfxMessageBox(L"无法打开目标进程"); // KillTimer(m_ntime); //计算DLL路径需要多大内存 int cb=(1+lstrlenW(pszLibFile))*sizeof(WCHAR); //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区 pszLibFileRemote=(PWSTR)VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE); if(pszLibFileRemote==NULL) { AfxMessageBox(L"建立内存失败"); CloseHandle(hRemoteProcess); return; } //使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间 BOOL iReturnCode=WriteProcessMemory (hRemoteProcess,pszLibFileRemote,(PVOID)pszLibFile,cb,NULL); if(!iReturnCode) { AfxMessageBox(L"写入错误"); VirtualFreeEx(hRemoteProcess,NULL,0,MEM_RELEASE); CloseHandle(hRemoteThread); CloseHandle(hRemoteProcess); return; } //计算loadlibraryW入口地址 HMODULE hModule=LoadLibrary(L"C:\\WINDOWS\\system32\\kernel32"); PTHREAD_START_ROUTINE pfnStartAddr=( PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW"); hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL); if(hRemoteThread==NULL) { //等待线程结束 WaitForSingleObject(hRemoteThread,INFINITE); DWORD RetV; if(GetExitCodeThread(hRemoteThread,&RetV)) CloseHandle(hRemoteThread);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值