如何在内存中运行可执行程序?
如何在内存中运行可执行程序?
在内存中运行可执行程序
在内存中运行可执行程序,好处是可以给程序加壳,加密源程序,静态反汇编无法获得PE输入节,但是因为运行后仍然是独立的进程,所以没办法防止远程线程注入,挂接API钩子。

 typedefIMAGE_SECTION_HEADER( * PIMAGE_SECTION_HEADERS)[ 1 ];
typedefIMAGE_SECTION_HEADER( * PIMAGE_SECTION_HEADERS)[ 1 ];
 // 计算对齐后的大小
 // 计算对齐后的大小 unsigned long GetAlignedSize(unsigned long Origin,unsigned long Alignment)
 unsigned long GetAlignedSize(unsigned long Origin,unsigned long Alignment)
 {
 { return (Origin + Alignment - 1 ) / Alignment * Alignment;
 return (Origin + Alignment - 1 ) / Alignment * Alignment; }
} 
 // 计算加载pe并对齐需要占用多少内存
 // 计算加载pe并对齐需要占用多少内存 // 未直接使用OptionalHeader.SizeOfImage作为结果是因为据说有的编译器生成的exe这个值会填0
 // 未直接使用OptionalHeader.SizeOfImage作为结果是因为据说有的编译器生成的exe这个值会填0 unsigned long CalcTotalImageSize(PIMAGE_DOS_HEADERMzH
 unsigned long CalcTotalImageSize(PIMAGE_DOS_HEADERMzH ,unsigned long FileLen
,unsigned long FileLen ,PIMAGE_NT_HEADERSpeH
,PIMAGE_NT_HEADERSpeH ,PIMAGE_SECTION_HEADERSpeSecH)
,PIMAGE_SECTION_HEADERSpeSecH)
 {
 { unsigned long res;
unsigned long res; // 计算pe头的大小
 // 计算pe头的大小 res = GetAlignedSize(peH -> OptionalHeader.SizeOfHeaders,peH -> OptionalHeader.SectionAlignment);
 res = GetAlignedSize(peH -> OptionalHeader.SizeOfHeaders,peH -> OptionalHeader.SectionAlignment);
 // 计算所有节的大小
 // 计算所有节的大小 for ( int i = 0 ;i < peH -> FileHeader.NumberOfSections; ++ i)
 for ( int i = 0 ;i < peH -> FileHeader.NumberOfSections; ++ i)
 {
 { // 超出文件范围
 // 超出文件范围 if (peSecH[i] -> PointerToRawData + peSecH[i] -> SizeOfRawData > FileLen)
 if (peSecH[i] -> PointerToRawData + peSecH[i] -> SizeOfRawData > FileLen)
 {
 { return 0 ;
 return 0 ; }
}  else if (peSecH[i] -> VirtualAddress) // 计算对齐后某节的大小
 else if (peSecH[i] -> VirtualAddress) // 计算对齐后某节的大小 
  {
 { if (peSecH[i] -> Misc.VirtualSize)
 if (peSecH[i] -> Misc.VirtualSize)
 {
 { res = GetAlignedSize(peSecH[i] -> VirtualAddress + peSecH[i] -> Misc.VirtualSize
res = GetAlignedSize(peSecH[i] -> VirtualAddress + peSecH[i] -> Misc.VirtualSize ,peH -> OptionalHeader.SectionAlignment);
,peH -> OptionalHeader.SectionAlignment); }
}  else
 else
 {
 { res = GetAlignedSize(peSecH[i] -> VirtualAddress + peSecH[i] -> SizeOfRawData
res = GetAlignedSize(peSecH[i] -> VirtualAddress + peSecH[i] -> SizeOfRawData ,peH -> OptionalHeader.SectionAlignment);
,peH -> OptionalHeader.SectionAlignment); }
}  }
}  else if (peSecH[i] -> Misc.VirtualSize < peSecH[i] -> SizeOfRawData)
 else if (peSecH[i] -> Misc.VirtualSize < peSecH[i] -> SizeOfRawData)
 {
 { res += GetAlignedSize(peSecH[i] -> SizeOfRawData
res += GetAlignedSize(peSecH[i] -> SizeOfRawData ,peH -> OptionalHeader.SectionAlignment);
,peH -> OptionalHeader.SectionAlignment); }
}  else
 else
 {
 { res += GetAlignedSize(peSecH[i] -> Misc.VirtualSize
res += GetAlignedSize(peSecH[i] -> Misc.VirtualSize ,peH -> OptionalHeader.SectionAlignment);
,peH -> OptionalHeader.SectionAlignment); } // if_else
} // if_else } // for
 } // for 
  return res;
 return res; }
} 



 // 加载pe到内存并对齐所有节
 // 加载pe到内存并对齐所有节 BOOLAlignPEToMem( void * Buf
 BOOLAlignPEToMem( void * Buf , long Len
, long Len ,PIMAGE_NT_HEADERS & peH
,PIMAGE_NT_HEADERS & peH ,PIMAGE_SECTION_HEADERS & peSecH
,PIMAGE_SECTION_HEADERS & peSecH , void *& Mem
, void *& Mem ,unsigned long & ImageSize)
,unsigned long & ImageSize)
 {
 { PIMAGE_DOS_HEADERSrcMz; // DOS头
PIMAGE_DOS_HEADERSrcMz; // DOS头 PIMAGE_NT_HEADERSSrcPeH; // PE头
 PIMAGE_NT_HEADERSSrcPeH; // PE头 PIMAGE_SECTION_HEADERSSrcPeSecH; // 节表
 PIMAGE_SECTION_HEADERSSrcPeSecH; // 节表 
  SrcMz = (PIMAGE_DOS_HEADER)Buf;
SrcMz = (PIMAGE_DOS_HEADER)Buf;
 if (Len < sizeof (IMAGE_DOS_HEADER))
 if (Len < sizeof (IMAGE_DOS_HEADER)) return FALSE;
 return FALSE;
 if (SrcMz -> e_magic != IMAGE_DOS_SIGNATURE)
 if (SrcMz -> e_magic != IMAGE_DOS_SIGNATURE) return FALSE;
 return FALSE;
 if (Len < SrcMz -> e_lfanew + ( long ) sizeof (IMAGE_NT_HEADERS))
 if (Len < SrcMz -> e_lfanew + ( long ) sizeof (IMAGE_NT_HEADERS)) return FALSE;
 return FALSE;
 SrcPeH = (PIMAGE_NT_HEADERS)(( int )SrcMz + SrcMz -> e_lfanew);
SrcPeH = (PIMAGE_NT_HEADERS)(( int )SrcMz + SrcMz -> e_lfanew); if (SrcPeH -> Signature != IMAGE_NT_SIGNATURE)
 if (SrcPeH -> Signature != IMAGE_NT_SIGNATURE) return FALSE;
 return FALSE;
 if ((SrcPeH -> FileHeader.Characteristics & IMAGE_FILE_DLL) ||
 if ((SrcPeH -> FileHeader.Characteristics & IMAGE_FILE_DLL) || (SrcPeH -> FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE == 0 ) ||
(SrcPeH -> FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE == 0 ) || (SrcPeH -> FileHeader.SizeOfOptionalHeader != sizeof (IMAGE_OPTIONAL_HEADER)))
(SrcPeH -> FileHeader.SizeOfOptionalHeader != sizeof (IMAGE_OPTIONAL_HEADER)))
 {
 { return FALSE;
 return FALSE; }
} 

 SrcPeSecH = (PIMAGE_SECTION_HEADERS)(( int )SrcPeH + sizeof (IMAGE_NT_HEADERS));
SrcPeSecH = (PIMAGE_SECTION_HEADERS)(( int )SrcPeH + sizeof (IMAGE_NT_HEADERS)); ImageSize = CalcTotalImageSize(SrcMz,Len,SrcPeH,SrcPeSecH);
ImageSize = CalcTotalImageSize(SrcMz,Len,SrcPeH,SrcPeSecH);
 if (ImageSize == 0 )
 if (ImageSize == 0 ) return FALSE;
 return FALSE;
 Mem = VirtualAlloc(NULL,ImageSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE); // 分配内存
Mem = VirtualAlloc(NULL,ImageSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE); // 分配内存 if (Mem != NULL)
 if (Mem != NULL)
 {
 { // 计算需要复制的PE头字节数
 // 计算需要复制的PE头字节数 unsigned long l = SrcPeH -> OptionalHeader.SizeOfHeaders;
 unsigned long l = SrcPeH -> OptionalHeader.SizeOfHeaders; for ( int i = 0 ;i < SrcPeH -> FileHeader.NumberOfSections; ++ i)
 for ( int i = 0 ;i < SrcPeH -> FileHeader.NumberOfSections; ++ i)
 {
 { if ((SrcPeSecH[i] -> PointerToRawData) &&
 if ((SrcPeSecH[i] -> PointerToRawData) && (SrcPeSecH[i] -> PointerToRawData < l))
(SrcPeSecH[i] -> PointerToRawData < l))
 {
 { l = SrcPeSecH[i] -> PointerToRawData;
l = SrcPeSecH[i] -> PointerToRawData; }
}  }
}  memmove(Mem,SrcMz,l);
memmove(Mem,SrcMz,l); peH = (PIMAGE_NT_HEADERS)(( int )Mem + ((PIMAGE_DOS_HEADER)Mem) -> e_lfanew);
peH = (PIMAGE_NT_HEADERS)(( int )Mem + ((PIMAGE_DOS_HEADER)Mem) -> e_lfanew); peSecH = (PIMAGE_SECTION_HEADERS)(( int )peH + sizeof (IMAGE_NT_HEADERS));
peSecH = (PIMAGE_SECTION_HEADERS)(( int )peH + sizeof (IMAGE_NT_HEADERS));
 void * Pt = ( void * )((unsigned long )Mem
 void * Pt = ( void * )((unsigned long )Mem + GetAlignedSize(peH -> OptionalHeader.SizeOfHeaders
 + GetAlignedSize(peH -> OptionalHeader.SizeOfHeaders ,peH -> OptionalHeader.SectionAlignment)
,peH -> OptionalHeader.SectionAlignment) );
);
 for (i = 0 ;i < peH -> FileHeader.NumberOfSections; ++ i)
 for (i = 0 ;i < peH -> FileHeader.NumberOfSections; ++ i)
 {
 { // 定位该节在内存中的位置
 // 定位该节在内存中的位置 if (peSecH[i] -> VirtualAddress)
 if (peSecH[i] -> VirtualAddress) Pt = ( void * )((unsigned long )Mem + peSecH[i] -> VirtualAddress);
Pt = ( void * )((unsigned long )Mem + peSecH[i] -> VirtualAddress);
 if (peSecH[i] -> SizeOfRawData)
 if (peSecH[i] -> SizeOfRawData)
 {
 { // 复制数据到内存
 // 复制数据到内存 memmove(Pt,( const void * )((unsigned long )(SrcMz) + peSecH[i] -> PointerToRawData),peSecH[i] -> SizeOfRawData);
 memmove(Pt,( const void * )((unsigned long )(SrcMz) + peSecH[i] -> PointerToRawData),peSecH[i] -> SizeOfRawData); if (peSecH[i] -> Misc.VirtualSize < peSecH[i] -> SizeOfRawData)
 if (peSecH[i] -> Misc.VirtualSize < peSecH[i] -> SizeOfRawData) Pt = ( void * )((unsigned long )Pt + GetAlignedSize(peSecH[i] -> SizeOfRawData,peH -> OptionalHeader.SectionAlignment));
Pt = ( void * )((unsigned long )Pt + GetAlignedSize(peSecH[i] -> SizeOfRawData,peH -> OptionalHeader.SectionAlignment)); else // pt定位到下一节开始位置
 else // pt定位到下一节开始位置 Pt = ( void * )((unsigned long )Pt + GetAlignedSize(peSecH[i] -> Misc.VirtualSize,peH -> OptionalHeader.SectionAlignment));
 Pt = ( void * )((unsigned long )Pt + GetAlignedSize(peSecH[i] -> Misc.VirtualSize,peH -> OptionalHeader.SectionAlignment)); }
}  else
 else
 {
 { Pt = ( void * )((unsigned long )Pt + GetAlignedSize(peSecH[i] -> Misc.VirtualSize,peH -> OptionalHeader.SectionAlignment));
Pt = ( void * )((unsigned long )Pt + GetAlignedSize(peSecH[i] -> Misc.VirtualSize,peH -> OptionalHeader.SectionAlignment)); }
}  }
}  }
}  return TRUE;
 return TRUE; }
} 


 typedef void * (__stdcall * pfVirtualAllocEx)(unsigned long , void * ,unsigned long ,unsigned long ,unsigned long );
typedef void * (__stdcall * pfVirtualAllocEx)(unsigned long , void * ,unsigned long ,unsigned long ,unsigned long ); pfVirtualAllocExMyVirtualAllocEx = NULL;
pfVirtualAllocExMyVirtualAllocEx = NULL;
 BOOLIsNT()
BOOLIsNT()
 {
 { return MyVirtualAllocEx != NULL;
 return MyVirtualAllocEx != NULL; }
} 
 // 生成外壳程序命令行
 // 生成外壳程序命令行 char * PrepareShellExe( char * CmdParam,unsigned long BaseAddr,unsigned long Ima
 char * PrepareShellExe( char * CmdParam,unsigned long BaseAddr,unsigned long Ima