[求助]内存写入注入
2020-06-30 21:17:04 Author: bbs.pediy.com(查看原文) 阅读量:327 收藏

各位大佬们,我在做内存写入注入的时候,使用的方法是首先,通过自己写的PE解释器,查看进程PID,这个就是写入进程了,然后通过一个进程读取,一个磁盘exe,拉伸,修复重定位后,注入目标进程,由于还没有修复IAT表所,在把自己镜像修复重定位后注入进去(为什么要注入两个镜像呢),因为自己的镜像里有修复IAT的函数,在创建远程线程执行 修复IAT的函数,修复IAT的函数最后有一个JMP跳转到  IMAGEBSE+OEP 执行真正要执行的注入的程序了,(注意一定要在目标进程中修复IAT  因为DLL必须要加载进去,否则无法执行的)

注入都是可以成功的也是可以执行的,通过了测试,但是我把一个Win32窗口程序注入控制台程序,Win32窗口程序却弹不出窗口不知道为什么?
而且吧一个控制台循环产生MessageBox的程序,注入Win32成功 会不停打印MessageBox,求教一个看雪的大佬们,以前辈们见多识广的眼光,如果能指点一二,相信对我就收获良多,下面的代码共享了自己写的没参考 注入了两次镜像傻的狠,希望也能对一些朋友产生一些帮助 ,还有程序里的开辟的指针都么有释放,时间紧

// 内存写入注入进程.cpp : Defines the entry point for the console application.
//

// 贴入exe.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <Windows.h>

#define PID 0x9E8

#define EXEPATH "C:\Documents and Settings\Administrator\桌面\测试贴入.exe"

#define SAVE "C:\Documents and Settings\Administrator\桌面\1111.exe"

#define BASE 0x1000000
char Mem1=NULL; //读取磁盘文件的FileBuf
char
Mem2=NULL; //将磁盘问的Filebuf拉伸成ImageBuf
char* Mem3=NULL; //自己进程的Imagebase 因为IAT表代表在自己的进程中
DWORD FileSize=0;
DWORD ImageBase=0;
DWORD SizeofImage=0;

DWORD CurrentImageBase=0;
DWORD CuurentSizeofImage=0;
DWORD OEP=0;
HANDLE Heap=0;

int SaveFile();
int RestoreIATTaber(DWORD MemBase);
int ImageBuffToFileBuff();
int RestoreReLcationTaber(DWORD MemAddr,DWORD NewImagebase,DWORD loImageBase);

int ReadCurrentImageBuff(){
HMODULE Hmoudle=GetModuleHandle(NULL);
if(NULL==Hmoudle){
MessageBox(NULL,"获取当前进程模块失败",0,0);
return 0;
}
PIMAGE_DOS_HEADER PeStructDosHeader=NULL;
PIMAGE_FILE_HEADER PeStructFileHeader=NULL;
PIMAGE_OPTIONAL_HEADER PeStructOptionHeader=NULL;

PeStructDosHeader=(PIMAGE_DOS_HEADER)Hmoudle;
PeStructFileHeader=(PIMAGE_FILE_HEADER)((DWORD)PeStructDosHeader+PeStructDosHeader->e_lfanew+4);
PeStructOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)PeStructFileHeader+sizeof(IMAGE_FILE_HEADER));

CurrentImageBase=PeStructOptionHeader->ImageBase;
CuurentSizeofImage=PeStructOptionHeader->SizeOfImage;

Mem3=(char*)VirtualAlloc(NULL,CuurentSizeofImage,MEM_RESERVE | MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(NULL==Mem3){
    int c=GetLastError();
    MessageBox(0,"VirtualAlloc开辟保存Current进程imagebuf失败",0,0);
    return 0;
}
memcpy(Mem3,Hmoudle,CuurentSizeofImage);

return 1;

}
int ReadData(){
HANDLE hFile=CreateFile(EXEPATH,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(NULL==hFile){
MessageBox(NULL,"打开文件失败",0,0);
return 0;
}
FileSize=GetFileSize(hFile,NULL);
if(INVALID_FILE_SIZE==FileSize){
MessageBox(NULL,"获取函数大小失败",0,0);
CloseHandle(hFile);
return 0;
}
Heap=HeapCreate(0,FileSize,0);
if(NULL==Heap){
MessageBox(NULL,"创建进程私有堆失败",0,0);
CloseHandle(hFile);
return 0;
}

Mem1=(char*)HeapAlloc(Heap,HEAP_ZERO_MEMORY,FileSize);    //全都初始化为0
if(NULL==Mem1){
    MessageBox(NULL,"HeapAlloc开辟堆内存失败",0,0);
    CloseHandle(hFile);
    return 0;
}

DWORD LpSize=0;
if(!ReadFile(hFile,Mem1,FileSize,&LpSize,NULL)){
    MessageBox(NULL,"ReadFile函数失败",0,0);
    CloseHandle(hFile);
    return 0;
}
if(FileSize!=LpSize){
    MessageBox(0,"读取文件字节数和预期不一致",0,0);
    return 0;
}
CloseHandle(hFile);
return 1;

}
DWORD GetSizeofImagSize(){
PIMAGE_DOS_HEADER PeStructDosHeader=NULL;
PIMAGE_FILE_HEADER PeStructFileHeader=NULL;
PIMAGE_OPTIONAL_HEADER PeStructOptionHeader=NULL;

PeStructDosHeader=(PIMAGE_DOS_HEADER)Mem1;
PeStructFileHeader=(PIMAGE_FILE_HEADER)((DWORD)PeStructDosHeader+PeStructDosHeader->e_lfanew+4);
PeStructOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)PeStructFileHeader+sizeof(IMAGE_FILE_HEADER));

OEP=PeStructOptionHeader->AddressOfEntryPoint;
ImageBase=PeStructOptionHeader->ImageBase;
SizeofImage=PeStructOptionHeader->SizeOfImage;
return 1;

}
DWORD MallocMemroy(){

Mem2=(char*)VirtualAlloc((char*)BASE,SizeofImage,MEM_RESERVE | MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(NULL==Mem2){
    int c=GetLastError();
    MessageBox(0,"VirtualAlloc开辟内存失败",0,0);
    return 0;
}
return 1;

}
int FIleBufToImageBuff(){
PIMAGE_DOS_HEADER PeStructDosHeader=NULL;
PIMAGE_FILE_HEADER PeStructFileHeader=NULL;
PIMAGE_OPTIONAL_HEADER PeStructOptionHeader=NULL;
PIMAGE_SECTION_HEADER PeStructSetionHeader=NULL;

PeStructDosHeader=(PIMAGE_DOS_HEADER)Mem1;
PeStructFileHeader=(PIMAGE_FILE_HEADER)((DWORD)PeStructDosHeader+PeStructDosHeader->e_lfanew+4);
PeStructOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)PeStructFileHeader+sizeof(IMAGE_FILE_HEADER));
PeStructSetionHeader=(PIMAGE_SECTION_HEADER)((DWORD)PeStructOptionHeader+PeStructFileHeader->SizeOfOptionalHeader);

DWORD VirtualAddress=0;
DWORD PointerToRawData=0;
DWORD SizeOfRawData=0;
memcpy(Mem2,Mem1,PeStructOptionHeader->SizeOfHeaders);                    //cpy PE Head

for(int i=0;i<PeStructFileHeader->NumberOfSections;i++){
    VirtualAddress=PeStructSetionHeader->VirtualAddress;
    PointerToRawData=PeStructSetionHeader->PointerToRawData;
    SizeOfRawData=PeStructSetionHeader->SizeOfRawData;
    memcpy(Mem2+VirtualAddress,Mem1+PointerToRawData,SizeOfRawData);
    PeStructSetionHeader++;
}
return 1;

}
int InjectMem2(HANDLE hProcess){ //Mem2 注入磁盘文件
char Dest2=(char)VirtualAllocEx(hProcess,NULL,SizeofImage,MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(NULL==Dest2){
MessageBox(NULL,"目标进程开辟第一块空间失败",0,0);
return 0;
}
if(!RestoreReLcationTaber((DWORD)Mem2,(DWORD)Dest2,ImageBase)){
return 0;
}
DWORD length=0;
if(!WriteProcessMemory(hProcess,Dest2,Mem2,SizeofImage,&length)){
int c=GetLastError();
MessageBox(NULL,"向目标进程中写入镜像失败",0,0);
return 0;
}
if(ImageBase==length){
MessageBox(NULL,"向目标进程中写入字节数不对",0,0);
return 0;
}
memset(Mem2,0,SizeofImage);
if(!ReadProcessMemory(hProcess,Dest2,Mem2,SizeofImage,&length)){
MessageBox(NULL,"读取目表进程内容失败",0,0);
return 0;
}
if(ImageBase==length){
MessageBox(NULL,"从目标进程中读取字节数不对",0,0);
return 0;
}

ImageBuffToFileBuff();
if(!SaveFile()){
    return -5;
}
return (DWORD)Dest2;

}
int InjectMem3(HANDLE hProcess,DWORD PosBase){ //注入字节 Mem3是自己
char Dest1=(char)VirtualAllocEx(hProcess,NULL,CuurentSizeofImage,MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(NULL==Dest1){
MessageBox(NULL,"目标进程开辟第一块空间失败",0,0);
return 0;
}
if(!RestoreReLcationTaber((DWORD)Mem3,(DWORD)Dest1,CurrentImageBase)){
return 0;
}
DWORD length=0;
if(!WriteProcessMemory(hProcess,Dest1,Mem3,CuurentSizeofImage,&length)){
int c=GetLastError();
MessageBox(NULL,"向目标进程中写入镜像失败",0,0);
return 0;
}
if(ImageBase==length){
MessageBox(NULL,"向目标进程中写入字节数不对",0,0);
return 0;
}

typedef  int(*ADDR)(DWORD);
DWORD  Rva=(DWORD)RestoreIATTaber-CurrentImageBase;
ADDR   addr=(int (__cdecl *)(unsigned long))(Rva+Dest1);

HANDLE hThread=CreateRemoteThread(hProcess,0,0,(LPTHREAD_START_ROUTINE)addr,(void*)PosBase,0,0);
if(NULL==hThread){
    MessageBox(NULL,"创建远程线程失败",0,0);
    return 0;
}
DWORD Code=0;
WaitForSingleObject(hThread,-1);                //永久等待直到线程返回
GetExitCodeThread(hThread,&Code);

}
int OpenDestProcess(){
HANDLE hProcess=OpenProcess( PROCESS_ALL_ACCESS,FALSE,PID);
if(NULL==hProcess){
MessageBox(NULL,"打开进程失败",0,0);
return 0;
}
DWORD Pos=0;
if(!(Pos=InjectMem2(hProcess))){ //先注入磁盘镜像
return 0;
}
if(!(InjectMem3(hProcess,Pos))){ //在注入自己的镜像
return 0;
}

}
int RestoreReLcationTaber(DWORD MemAddr,DWORD NewImagebase,DWORD oldImageBase){
PIMAGE_DOS_HEADER PeStructDosHeader=NULL;
PIMAGE_FILE_HEADER PeStructFileHeader=NULL;
PIMAGE_OPTIONAL_HEADER PeStructOptionHeader=NULL;
PIMAGE_BASE_RELOCATION PeStructReLocatHeader=NULL;

PeStructDosHeader=(PIMAGE_DOS_HEADER)MemAddr;                                    //Mem2获取Mem3的其实地址
PeStructFileHeader=(PIMAGE_FILE_HEADER)((DWORD)PeStructDosHeader+PeStructDosHeader->e_lfanew+4);
PeStructOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)PeStructFileHeader+sizeof(IMAGE_FILE_HEADER));

if(PeStructOptionHeader->DataDirectory[5].VirtualAddress){
    PeStructReLocatHeader=(PIMAGE_BASE_RELOCATION)((DWORD)MemAddr+PeStructOptionHeader->DataDirectory[5].VirtualAddress);
}
else{
    MessageBox(NULL,"不存在重定位表",0,0);
    return 0;
}

PeStructOptionHeader->ImageBase=NewImagebase;


DWORD* Item=NULL;
WORD* Data=NULL;
while(PeStructReLocatHeader->VirtualAddress&&PeStructReLocatHeader->SizeOfBlock){
    Data=(WORD*)((DWORD)PeStructReLocatHeader+8);
    for(int i=0;i<(PeStructReLocatHeader->SizeOfBlock-8)/2;i++){
        if((Data[i]&0xF000)==0x3000){
            Item=(DWORD*)((DWORD)MemAddr+PeStructReLocatHeader->VirtualAddress+(Data[i]&0x0FFF));
            *Item=*Item+(DWORD)NewImagebase-oldImageBase;
        }
    }
    PeStructReLocatHeader=(PIMAGE_BASE_RELOCATION)((DWORD)PeStructReLocatHeader+PeStructReLocatHeader->SizeOfBlock);
}
return 1;

}
int RestoreIATTaber(DWORD MemBase){

PIMAGE_DOS_HEADER            PeStructDosHeader=NULL;
PIMAGE_FILE_HEADER            PeStructFileHeader=NULL;
PIMAGE_OPTIONAL_HEADER        PeStructOptionHeader=NULL;
PIMAGE_BASE_RELOCATION        PeStructReLocatHeader=NULL;
PIMAGE_IMPORT_DESCRIPTOR    PeStructImPortHeader=NULL;

PeStructDosHeader=(PIMAGE_DOS_HEADER)MemBase;
PeStructFileHeader=(PIMAGE_FILE_HEADER)((DWORD)PeStructDosHeader+PeStructDosHeader->e_lfanew+4);
PeStructOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)PeStructFileHeader+sizeof(IMAGE_FILE_HEADER));

if(PeStructOptionHeader->DataDirectory[1].VirtualAddress){
    PeStructImPortHeader=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)MemBase+PeStructOptionHeader->DataDirectory[1].VirtualAddress);
}
else{
    MessageBox(NULL,"不存在导入表",0,0);
    return 0;
}
char*  DLLName=NULL;
HMODULE hMoudle=NULL;
DWORD* INT=NULL;
DWORD* IAT=NULL;
char *FuntionName=NULL;
while(PeStructImPortHeader->FirstThunk&&PeStructImPortHeader->OriginalFirstThunk){
    DLLName=(char*)(MemBase+PeStructImPortHeader->Name);
    hMoudle=LoadLibrary(DLLName);
    if(NULL==hMoudle){
        MessageBox(NULL,"LoadLibrary 加载DLL失败",0,0);
        return 0;
    }
    INT=(DWORD*)((DWORD)MemBase+PeStructImPortHeader->OriginalFirstThunk);
    IAT=(DWORD*)((DWORD)MemBase+PeStructImPortHeader->FirstThunk);
    while(*INT){
        if((*INT)&0x80000000==0x80000000){

        }
        else{
            FuntionName=(char*)(MemBase+*INT+2);
            *IAT=(DWORD)GetProcAddress(hMoudle,FuntionName);
            if(!*INT){
                MessageBox(NULL,"GetProcAddress通过函数名获取函数地址出现错误",0,0);
                return 0;
            }
        }
        INT++;
        IAT++;
    }
    PeStructImPortHeader++;
}
DWORD jmpip=(DWORD)MemBase+PeStructOptionHeader->AddressOfEntryPoint;
__asm{
    jmp  jmpip;
}
return 100;

}
int ImageBuffToFileBuff(){
PIMAGE_DOS_HEADER PeStructDosHeader=NULL;
PIMAGE_FILE_HEADER PeStructFileHeader=NULL;
PIMAGE_OPTIONAL_HEADER PeStructOptionHeader=NULL;
PIMAGE_SECTION_HEADER PeStructSetionHeader=NULL;

PeStructDosHeader=(PIMAGE_DOS_HEADER)Mem2;
PeStructFileHeader=(PIMAGE_FILE_HEADER)((DWORD)PeStructDosHeader+PeStructDosHeader->e_lfanew+4);
PeStructOptionHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)PeStructFileHeader+sizeof(IMAGE_FILE_HEADER));
PeStructSetionHeader=(PIMAGE_SECTION_HEADER)((DWORD)PeStructOptionHeader+PeStructFileHeader->SizeOfOptionalHeader);

DWORD VirtualAddress=0;
DWORD PointerToRawData=0;
DWORD SizeOfRawData=0;
//memcpy(Mem1,0,FileSize);
memcpy(Mem1,Mem2,PeStructOptionHeader->SizeOfHeaders);                    //cpy PE Head

for(int i=0;i<PeStructFileHeader->NumberOfSections;i++){
    VirtualAddress=PeStructSetionHeader->VirtualAddress;
    PointerToRawData=PeStructSetionHeader->PointerToRawData;
    SizeOfRawData=PeStructSetionHeader->SizeOfRawData;
    memcpy(Mem1+PointerToRawData,Mem2+VirtualAddress,SizeOfRawData);
    PeStructSetionHeader++;
}
return 1;

}
int SaveFile(){
HANDLE hFile=CreateFile(SAVE,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS, //如果文件存在则重写
FILE_ATTRIBUTE_NORMAL,
NULL);
if(NULL==hFile){
MessageBox(NULL,"打开文件失败",0,0);
return 0;
}
DWORD Size=0;

if(!WriteFile(hFile,Mem1,FileSize,&Size,NULL)){
    int c=GetLastError();
    MessageBox(NULL,"WriteFile写入文件失败",0,0);
    return 0;
}
HeapFree(Heap,HEAP_NO_SERIALIZE,Mem1);
CloseHandle(hFile);

}

int main(int argc, char* argv[])
{
if(!ReadCurrentImageBuff()){ //读取自己的imagebuf 到mem3内存没有修复重定位
return 0;
}
if(!ReadData()){ //读取磁盘上一个文件的FIleBuf 保存在开辟Mem1空间中个
return 0;
}
GetSizeofImagSize(); //获取这个磁盘的OEP imagebase sizeof等信息
if(!MallocMemroy()){ //开辟一个Mem3准备保存 Mem1拉伸后的内容
return 0;
}
FIleBufToImageBuff(); //将FIleBuf拉伸成 ImageBuf 并保存在Mme2中 此时Mme2和Mem3都没修复重定位

#if 0
if(!RestoreIATTaber()){
return -4;
}
if(!RestoreReLcationTaber()){ //修复重定位
return 0;
}
ImageBuffToFileBuff();
if(!SaveFile()){
return -5;
}

#endif
OpenDestProcess();

printf("Hello World!\n");
return 0;

}


文章来源: https://bbs.pediy.com/thread-260304.htm
如有侵权请联系:admin#unsafe.sh