1,088,879 Community Members

Reversing a Algorithm

Member Avatar
Light Poster
48 posts since Dec 2007
Reputation Points: 10
Solved Threads: 1
Skill Endorsements: 0
 
0
 

hey,

I have a program that uses a certain algorithm to decrypt dll files from the game, half-life. but once i have decrypted them, the game crashed whenever i try to start it with the un-encrypted files. How would I reverse the algorithm, making the program encrypt them instead of decrypting them. I have the code and it is posted below:

hldlldec.c:

  1. /*
  2. Copyright 2007 Luigi Auriemma
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. http://www.gnu.org/licenses/gpl.txt
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <stdint.h>
  19. #include <string.h>
  20. #include <sys/stat.h>
  21. #include <ctype.h>
  22. #include "pe.h"
  23. #define VER "0.1"
  24. #define round(n) (((n + (PE_align - 1)) / PE_align) * PE_align)
  25. void halflife_dll_decrypt(uint8_t *data, uint32_t datasz);
  26. void find_impexp_tables(uint8_t *base, uint32_t baseoff, uint32_t *impoff, uint32_t *impsz, uint32_t *expoff, uint32_t *expsz);
  27. void dump_section(FILE *fd, uint32_t num, uint8_t *data, uint32_t datasz);
  28. uint8_t *fd_read(uint8_t *name, int *fdlen);
  29. void fd_write(uint8_t *name, uint8_t *data, int datasz);
  30. void std_err(void);
  31. int dump = 0;
  32. uint8_t *in_file,
  33. *out_file;
  34. int main(int argc, char *argv[]) {
  35. uint32_t filelen;
  36. int i;
  37. uint8_t *filebuff;
  38. fputs("\n"
  39. "Half-life DLL decrypter and rebuilder "VER"\n"
  40. "by Luigi Auriemma\n"
  41. "e-mail: aluigi@autistici.org\n"
  42. "web: aluigi.org\n"
  43. "\n", stdout);
  44. if(argc < 3) {
  45. printf("\n"
  46. "Usage: %s [options] <input.DLL> <output.DLL>\n"
  47. "\n"
  48. "Options:\n"
  49. "-d dump all the sections of the DLL instead of building the PE file,\n"
  50. " use <output.DLL> as base for the sequential output filename\n"
  51. "\n", argv[0]);
  52. exit(1);
  53. }
  54. argc -= 2;
  55. for(i = 1; i < argc; i++) {
  56. if(((argv[i][0] != '-') && (argv[i][0] != '/')) || (strlen(argv[i]) != 2)) {
  57. printf("\nError: recheck your options (%s is not valid)\n", argv[i]);
  58. exit(1);
  59. }
  60. switch(argv[i][1]) {
  61. case 'd': dump = 1; break;
  62. default: {
  63. printf("\nError: wrong command-line argument (%s)\n\n", argv[i]);
  64. exit(1);
  65. } break;
  66. }
  67. }
  68. in_file = argv[argc];
  69. out_file = argv[argc + 1];
  70. filebuff = fd_read(in_file, &filelen);
  71. halflife_dll_decrypt(filebuff, filelen);
  72. printf("\n- the DLL has been decrypted and %s\n", dump
  73. ? "dumped in the various section files"
  74. : "rebuilt");
  75. free(filebuff);
  76. return(0);
  77. }
  78. void halflife_dll_decrypt(uint8_t *data, uint32_t datasz) {
  79. typedef struct {
  80. uint32_t Characteristics;
  81. uint32_t Sections;
  82. uint32_t copywhat;
  83. uint32_t ImageBase;
  84. uint32_t EntryPoint;
  85. uint32_t ImportTable;
  86. } hlhdr_t;
  87. typedef struct {
  88. uint32_t rva;
  89. uint32_t raw_size;
  90. uint32_t virtual_size;
  91. uint32_t file_offset;
  92. uint32_t zero;
  93. } hlsec_t;
  94. const static char *sec_names[4] = { ".text", ".rdata", ".data", ".rsrc" };
  95. hlhdr_t *hlhdr;
  96. hlsec_t *hlsec;
  97. FILE *fd;
  98. uint32_t i,
  99. fdoff,
  100. peoff;
  101. uint8_t chr,
  102. *base;
  103. if(*(uint32_t *)(data + 64) != 0x12345678) {
  104. printf("\nAlert: this DLL doesn't seem encrypted with the Valve algorithm\n");
  105. }
  106. base = data;
  107. data += 68;
  108. datasz -= 68;
  109. chr = 'W';
  110. for(i = 0; i < datasz; i++) {
  111. data[i] ^= chr;
  112. chr += data[i] + 'W';
  113. }
  114. hlhdr = (void *)data;
  115. hlsec = (void *)(data + sizeof(hlhdr_t));
  116. hlhdr->copywhat ^= 0x7a32bc85;
  117. hlhdr->ImageBase ^= 0x49c042d1;
  118. hlhdr->ImportTable ^= 0x872c3d47;
  119. hlhdr->EntryPoint -= 12;
  120. printf("\n"
  121. " Characteristics %08x\n"
  122. " Sections %08x\n"
  123. " copywhat %08x\n"
  124. " ImageBase %08x\n"
  125. " EntryPoint %08x\n"
  126. " ImportTable %08x\n",
  127. hlhdr->Characteristics,
  128. hlhdr->Sections,
  129. hlhdr->copywhat,
  130. hlhdr->ImageBase,
  131. hlhdr->EntryPoint,
  132. hlhdr->ImportTable);
  133. for(i = 0; i <= hlhdr->Sections; i++) {
  134. printf("\n"
  135. "- section %u\n"
  136. " raw_size %08x\n"
  137. " virtual_size %08x\n"
  138. " file_offset %08x\n"
  139. " rva %08x\n"
  140. " zero %08x\n",
  141. i,
  142. hlsec[i].raw_size,
  143. hlsec[i].virtual_size,
  144. hlsec[i].file_offset,
  145. hlsec[i].rva,
  146. hlsec[i].zero);
  147. if(dump) {
  148. dump_section(NULL, i, base + hlsec[i].file_offset, hlsec[i].virtual_size);
  149. }
  150. }
  151. if(dump) return;
  152. printf("\n");
  153. /* when all the section have been placed in memory */
  154. /* HL.EXE calls hlhdr->EntryPoint and then hlhdr->copywhat */
  155. /* copying a zone of the DLL in the HL.EXE process */
  156. /* IMPORTANT NOTE */
  157. /* all the PE stuff here and in pe.h seems to work fine */
  158. /* but for the moment I consider it only a work-around */
  159. /* so don't take it too seriously */
  160. for(i = 0; i <= hlhdr->Sections; i++) {
  161. PE_size_image += round(hlsec[i].raw_size);
  162. }
  163. PE_sections = hlhdr->Sections + 1;
  164. PE_size_code = hlsec[0].raw_size;
  165. PE_entry_point = hlhdr->EntryPoint - hlhdr->ImageBase;
  166. PE_base_code = hlsec[0].rva - hlhdr->ImageBase;
  167. PE_image_base = hlhdr->ImageBase;
  168. PE_Characteristics = hlhdr->Characteristics;
  169. printf("- search offsets and sizes of the import and export tables\n");
  170. PE_import_rva = hlhdr->ImportTable;
  171. find_impexp_tables(
  172. base + hlsec[1].file_offset,
  173. hlsec[1].rva,
  174. &PE_import_rva, &PE_import_size,
  175. &PE_export_rva, &PE_export_size);
  176. PE_import_rva -= PE_image_base;
  177. PE_export_rva -= PE_image_base;
  178. if(hlhdr->Sections >= 3) {
  179. PE_resource_rva = hlsec[3].rva - PE_image_base;
  180. PE_resource_size = hlsec[3].virtual_size;
  181. }
  182. printf("- now I try to build the PE DLL (experimental)\n\n");
  183. fd = fopen(out_file, "wb");
  184. if(!fd) std_err();
  185. PE_dos_fwrite(fd);
  186. PE_sign_fwrite(fd);
  187. PE_file_fwrite(fd);
  188. PE_optional_fwrite(fd);
  189. peoff = ftell(fd);
  190. fseek(fd, PE_base_code, SEEK_SET);
  191. for(i = 0; i <= hlhdr->Sections; i++) {
  192. fdoff = ftell(fd);
  193. printf(" section %u -> %08x -> %08x\n",
  194. i,
  195. (uint32_t)ftell(fd),
  196. hlsec[i].rva);
  197. dump_section(fd, i, base + hlsec[i].file_offset, hlsec[i].virtual_size);
  198. hlsec[i].file_offset = fdoff; // here file_offset becomes our new offset
  199. }
  200. fseek(fd, peoff, SEEK_SET);
  201. for(i = 0; i <= hlhdr->Sections; i++) {
  202. PE_Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE |
  203. IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA |
  204. IMAGE_SCN_MEM_WRITE;
  205. PE_virtual_size = hlsec[i].virtual_size;
  206. PE_rva = hlsec[i].rva;
  207. PE_raw_size = hlsec[i].raw_size;
  208. PE_file_offset = hlsec[i].file_offset;
  209. if(i < 4) {
  210. strcpy(PE_section_name, sec_names[i]);
  211. } else {
  212. sprintf(PE_section_name, "sec%u", i);
  213. }
  214. PE_section_fwrite(fd);
  215. }
  216. fclose(fd);
  217. }
  218. /* the following stupid function takes the data where starts the import table */
  219. /* and finds its size and the offset and size of the export table too */
  220. void find_impexp_tables(uint8_t *base, uint32_t baseoff, uint32_t *impoff, uint32_t *impsz, uint32_t *expoff, uint32_t *expsz) {
  221. uint32_t off,
  222. maxoff;
  223. uint16_t hint;
  224. uint8_t *data,
  225. *p;
  226. data = base + (*impoff - baseoff);
  227. p = data;
  228. maxoff = 0;
  229. while((off = *(uint32_t *)(p + 12))) {
  230. if(off > maxoff) maxoff = off;
  231. p += 20;
  232. }
  233. maxoff -= (baseoff - PE_image_base);
  234. p = base + maxoff;
  235. while(*p++);
  236. if((p - base) & 1) p++;
  237. while((hint = *(uint16_t *)p)) {
  238. p += 2;
  239. while(*p++);
  240. if((p - base) & 1) p++;
  241. }
  242. while(!*p) p++; // blah I think it's lame
  243. p -= ((p - base) & 3);
  244. p -= 4;
  245. *impsz = p - data;
  246. *expoff = (p - base) + baseoff;
  247. data = p;
  248. off = *(uint32_t *)(p + 12);
  249. off -= (baseoff - PE_image_base);
  250. p = base + off;
  251. while(*p) {
  252. while(*p++);
  253. }
  254. if((p - base) & 1) p++;
  255. *expsz = p - data;
  256. printf("- import table found: %08x -> %u\n", *impoff - baseoff, *impsz);
  257. printf("- export table found: %08x -> %u\n", *expoff - baseoff, *expsz);
  258. }
  259. void dump_section(FILE *fd, uint32_t num, uint8_t *data, uint32_t datasz) {
  260. uint32_t i,
  261. zero;
  262. uint8_t *fname = NULL,
  263. *p;
  264. if(dump) {
  265. fname = malloc(strlen(out_file) + 12);
  266. p = strrchr(out_file, '.');
  267. if(p) {
  268. sprintf(fname, "%.*s_%u.%s", p - out_file, out_file, num, p + 1);
  269. } else {
  270. sprintf(fname, "%s_%u.dll", out_file, num);
  271. }
  272. printf("- write %s\n", fname);
  273. fd = fopen(fname, "wb");
  274. if(!fd) std_err();
  275. }
  276. fwrite(data, datasz, 1, fd);
  277. if(dump) {
  278. fclose(fd);
  279. free(fname);
  280. } else {
  281. zero = round(datasz);
  282. for(i = datasz; i < zero; i++) {
  283. fputc(0, fd);
  284. }
  285. }
  286. }
  287. uint8_t *fd_read(uint8_t *name, int *fdlen) {
  288. struct stat xstat;
  289. FILE *fd;
  290. uint8_t *buff;
  291. printf("- open file %s\n", name);
  292. fd = fopen(name, "rb");
  293. if(!fd) std_err();
  294. fstat(fileno(fd), &xstat);
  295. buff = malloc(xstat.st_size);
  296. fread(buff, xstat.st_size, 1, fd);
  297. fclose(fd);
  298. *fdlen = xstat.st_size;
  299. return(buff);
  300. }
  301. void fd_write(uint8_t *name, uint8_t *data, int datasz) {
  302. FILE *fd;
  303. printf("- create file %s\n", name);
  304. fd = fopen(name, "rb");
  305. if(fd) {
  306. fclose(fd);
  307. printf("- file already exists, do you want to overwrite it (y/N)?\n ");
  308. fflush(stdin);
  309. if(tolower(fgetc(stdin)) != 'y') exit(1);
  310. }
  311. fd = fopen(name, "wb");
  312. if(!fd) std_err();
  313. fwrite(data, datasz, 1, fd);
  314. fclose(fd);
  315. }
  316. void std_err(void) {
  317. perror("\nError");
  318. exit(1);
  319. }

pe.h:

  1. /*
  2. Copyright 2007 Luigi Auriemma
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. http://www.gnu.org/licenses/gpl.txt
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <cstdint.h>
  19. #include <string.h>
  20. /* DEFINES */
  21. #define IMAGE_DOS_SIGNATURE 0x5A4D
  22. #define IMAGE_OS2_SIGNATURE 0x454E
  23. #define IMAGE_OS2_SIGNATURE_LE 0x454C
  24. #define IMAGE_VXD_SIGNATURE 0x454C
  25. #define IMAGE_NT_SIGNATURE 0x00004550
  26. #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
  27. #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
  28. #define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
  29. #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
  30. #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
  31. #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
  32. #define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
  33. #define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
  34. #define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
  35. #define IMAGE_SIZEOF_SHORT_NAME 8
  36. #define IMAGE_SIZEOF_SECTION_HEADER 40
  37. #define IMAGE_SIZEOF_SYMBOL 18
  38. #define IMAGE_SIZEOF_AUX_SYMBOL 18
  39. #define IMAGE_SIZEOF_RELOCATION 10
  40. #define IMAGE_SIZEOF_BASE_RELOCATION 8
  41. #define IMAGE_SIZEOF_LINENUMBER 6
  42. #define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
  43. #define IMAGE_FILE_MACHINE_I386 0x014c
  44. #define IMAGE_FILE_RELOCS_STRIPPED 1
  45. #define IMAGE_FILE_EXECUTABLE_IMAGE 2
  46. #define IMAGE_FILE_LINE_NUMS_STRIPPED 4
  47. #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8
  48. #define IMAGE_FILE_AGGRESIVE_WS_TRIM 16
  49. #define IMAGE_FILE_LARGE_ADDRESS_AWARE 32
  50. #define IMAGE_FILE_BYTES_REVERSED_LO 128
  51. #define IMAGE_FILE_32BIT_MACHINE 256
  52. #define IMAGE_FILE_DEBUG_STRIPPED 512
  53. #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 1024
  54. #define IMAGE_FILE_NET_RUN_FROM_SWAP 2048
  55. #define IMAGE_FILE_SYSTEM 4096
  56. #define IMAGE_FILE_DLL 8192
  57. #define IMAGE_FILE_UP_SYSTEM_ONLY 16384
  58. #define IMAGE_FILE_BYTES_REVERSED_HI 32768
  59. #define IMAGE_SUBSYSTEM_UNKNOWN 0
  60. #define IMAGE_SUBSYSTEM_NATIVE 1
  61. #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
  62. #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
  63. #define IMAGE_SUBSYSTEM_OS2_CUI 5
  64. #define IMAGE_SUBSYSTEM_POSIX_CUI 7
  65. #define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8
  66. #define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9
  67. #define IMAGE_SUBSYSTEM_XBOX 14
  68. #define IMAGE_SCN_CNT_CODE 32
  69. #define IMAGE_SCN_CNT_INITIALIZED_DATA 64
  70. #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128
  71. #define IMAGE_SCN_LNK_OTHER 256
  72. #define IMAGE_SCN_LNK_INFO 512
  73. #define IMAGE_SCN_TYPE_OVER 1024
  74. #define IMAGE_SCN_LNK_REMOVE 2048
  75. #define IMAGE_SCN_LNK_COMDAT 4096
  76. #define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
  77. #define IMAGE_SCN_MEM_NOT_CACHED 0x4000000
  78. #define IMAGE_SCN_MEM_NOT_PAGED 0x8000000
  79. #define IMAGE_SCN_MEM_SHARED 0x10000000
  80. #define IMAGE_SCN_MEM_EXECUTE 0x20000000
  81. #define IMAGE_SCN_MEM_READ 0x40000000
  82. #define IMAGE_SCN_MEM_WRITE 0x80000000
  83. /* STRUCTURES */
  84. typedef struct {
  85. uint16_t e_magic;
  86. uint16_t e_cblp;
  87. uint16_t e_cp;
  88. uint16_t e_crlc;
  89. uint16_t e_cparhdr;
  90. uint16_t e_minalloc;
  91. uint16_t e_maxalloc;
  92. uint16_t e_ss;
  93. uint16_t e_sp;
  94. uint16_t e_csum;
  95. uint16_t e_ip;
  96. uint16_t e_cs;
  97. uint16_t e_lfarlc;
  98. uint16_t e_ovno;
  99. uint16_t e_res[4];
  100. uint16_t e_oemid;
  101. uint16_t e_oeminfo;
  102. uint16_t e_res2[10];
  103. int32_t e_lfanew;
  104. } IMAGE_DOS;
  105. typedef struct {
  106. uint16_t Machine;
  107. uint16_t NumberOfSections;
  108. uint32_t TimeDateStamp;
  109. uint32_t PointerToSymbolTable;
  110. uint32_t NumberOfSymbols;
  111. uint16_t SizeOfOptionalHeader;
  112. uint16_t Characteristics;
  113. } IMAGE_FILE;
  114. typedef struct {
  115. uint32_t VirtualAddress;
  116. uint32_t Size;
  117. } IMAGE_DATA_DIRECTORY;
  118. typedef struct {
  119. uint16_t Magic;
  120. uint8_t MajorLinkerVersion;
  121. uint8_t MinorLinkerVersion;
  122. uint32_t SizeOfCode;
  123. uint32_t SizeOfInitializedData;
  124. uint32_t SizeOfUninitializedData;
  125. uint32_t AddressOfEntryPoint;
  126. uint32_t BaseOfCode;
  127. uint32_t BaseOfData;
  128. uint32_t ImageBase;
  129. uint32_t SectionAlignment;
  130. uint32_t FileAlignment;
  131. uint16_t MajorOperatingSystemVersion;
  132. uint16_t MinorOperatingSystemVersion;
  133. uint16_t MajorImageVersion;
  134. uint16_t MinorImageVersion;
  135. uint16_t MajorSubsystemVersion;
  136. uint16_t MinorSubsystemVersion;
  137. uint32_t Win32VersionValue;
  138. uint32_t SizeOfImage;
  139. uint32_t SizeOfHeaders;
  140. uint32_t CheckSum;
  141. uint16_t Subsystem;
  142. uint16_t DllCharacteristics;
  143. uint32_t SizeOfStackReserve;
  144. uint32_t SizeOfStackCommit;
  145. uint32_t SizeOfHeapReserve;
  146. uint32_t SizeOfHeapCommit;
  147. uint32_t LoaderFlags;
  148. uint32_t NumberOfRvaAndSizes;
  149. IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
  150. } IMAGE_OPTIONAL32;
  151. #define PE_DIR_ExportTable DataDirectory[0]
  152. #define PE_DIR_ImportTable DataDirectory[1]
  153. #define PE_DIR_Resource DataDirectory[2]
  154. #define PE_DIR_Exception DataDirectory[3]
  155. #define PE_DIR_Security DataDirectory[4]
  156. #define PE_DIR_Relocation DataDirectory[5]
  157. #define PE_DIR_Debug DataDirectory[6]
  158. #define PE_DIR_Copyright DataDirectory[7]
  159. #define PE_DIR_GlobalPtr DataDirectory[8]
  160. #define PE_DIR_TLSTable DataDirectory[9]
  161. #define PE_DIR_LoadConfig DataDirectory[10]
  162. #define PE_DIR_BoundImport DataDirectory[11]
  163. #define PE_DIR_IAT DataDirectory[12]
  164. #define PE_DIR_DelayImport DataDirectory[13]
  165. #define PE_DIR_COM DataDirectory[14]
  166. #define PE_DIR_Reserved DataDirectory[15]
  167. typedef struct {
  168. uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
  169. union {
  170. uint32_t PhysicalAddress;
  171. uint32_t VirtualSize;
  172. } Misc;
  173. uint32_t VirtualAddress;
  174. uint32_t SizeOfRawData;
  175. uint32_t PointerToRawData;
  176. uint32_t PointerToRelocations;
  177. uint32_t PointerToLinenumbers;
  178. uint16_t NumberOfRelocations;
  179. uint16_t NumberOfLinenumbers;
  180. uint32_t Characteristics;
  181. } IMAGE_SECTION_HEADER;
  182. /* GLOBAL VARIABLES */
  183. uint32_t PE_align = 0x1000,
  184. PE_sections = 0,
  185. PE_size_code = 0,
  186. PE_entry_point = 0,
  187. PE_base_code = 0x00001000,
  188. PE_image_base = 0,
  189. PE_size_image = 0,
  190. PE_Characteristics = 0,
  191. PE_virtual_size = 0,
  192. PE_file_offset = 0,
  193. PE_raw_size = 0,
  194. PE_rva = 0,
  195. PE_export_rva = 0,
  196. PE_export_size = 0,
  197. PE_import_rva = 0,
  198. PE_import_size = 0,
  199. PE_iat_rva = 0,
  200. PE_iat_size = 0,
  201. PE_resource_rva = 0,
  202. PE_resource_size = 0;
  203. uint8_t PE_section_name[IMAGE_SIZEOF_SHORT_NAME];
  204. /* FUNCTIONS */
  205. void PE_dos_fwrite(FILE *fd) {
  206. IMAGE_DOS hdr;
  207. const static uint8_t dosdata[64] =
  208. "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21\x54\x68"
  209. "\x69\x73\x20\x70\x72\x6F\x67\x72\x61\x6D\x20\x63\x61\x6E\x6E\x6F"
  210. "\x74\x20\x62\x65\x20\x72\x75\x6E\x20\x69\x6E\x20\x44\x4F\x53\x20"
  211. "\x6D\x6F\x64\x65\x2E\x0D\x0D\x0A\x24\x00\x00\x00\x00\x00\x00\x00";
  212. memset(&hdr, 0, sizeof(hdr));
  213. hdr.e_magic = IMAGE_DOS_SIGNATURE;
  214. hdr.e_cblp = 0x0090;
  215. hdr.e_cp = 0x0003;
  216. hdr.e_cparhdr = 0x0004;
  217. hdr.e_maxalloc = 0xffff;
  218. hdr.e_sp = 0x00b8;
  219. hdr.e_lfarlc = 0x0040;
  220. hdr.e_lfanew = sizeof(hdr) + sizeof(dosdata);
  221. fwrite(&hdr, sizeof(hdr), 1, fd);
  222. fwrite(&dosdata, sizeof(dosdata), 1, fd);
  223. }
  224. void PE_sign_fwrite(FILE *fd) {
  225. uint32_t hdr;
  226. hdr = IMAGE_NT_SIGNATURE;
  227. fwrite(&hdr, sizeof(hdr), 1, fd);
  228. }
  229. void PE_file_fwrite(FILE *fd) {
  230. IMAGE_FILE hdr;
  231. memset(&hdr, 0, sizeof(hdr));
  232. hdr.Machine = IMAGE_FILE_MACHINE_I386;
  233. hdr.NumberOfSections = PE_sections;
  234. hdr.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL32);
  235. hdr.Characteristics = PE_Characteristics;
  236. fwrite(&hdr, sizeof(hdr), 1, fd);
  237. }
  238. void PE_optional_fwrite(FILE *fd) {
  239. IMAGE_OPTIONAL32 hdr;
  240. memset(&hdr, 0, sizeof(hdr));
  241. hdr.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
  242. hdr.SizeOfCode = PE_size_code;
  243. hdr.SizeOfInitializedData = PE_size_image - PE_size_code;
  244. hdr.AddressOfEntryPoint = PE_entry_point;
  245. hdr.BaseOfCode = PE_base_code;
  246. hdr.ImageBase = PE_image_base;
  247. hdr.SectionAlignment = PE_align;
  248. hdr.FileAlignment = PE_align;
  249. hdr.MajorOperatingSystemVersion = 4;
  250. hdr.MajorSubsystemVersion = 4;
  251. hdr.SizeOfImage = PE_size_image;
  252. hdr.SizeOfHeaders = PE_base_code;
  253. hdr.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
  254. hdr.SizeOfStackReserve = 0x00100000;
  255. hdr.SizeOfStackCommit = 0x00001000;
  256. hdr.SizeOfHeapReserve = 0x00100000;
  257. hdr.SizeOfHeapCommit = 0x00001000;
  258. hdr.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
  259. hdr.PE_DIR_ExportTable.VirtualAddress = PE_export_rva;
  260. hdr.PE_DIR_ExportTable.Size = PE_export_size;
  261. hdr.PE_DIR_ImportTable.VirtualAddress = PE_import_rva;
  262. hdr.PE_DIR_ImportTable.Size = PE_import_size;
  263. hdr.PE_DIR_Resource.VirtualAddress = PE_resource_rva;
  264. hdr.PE_DIR_Resource.Size = PE_resource_size;
  265. fwrite(&hdr, sizeof(hdr), 1, fd);
  266. }
  267. void PE_section_fwrite(FILE *fd) {
  268. IMAGE_SECTION_HEADER hdr;
  269. memset(&hdr, 0, sizeof(hdr));
  270. strncpy(hdr.Name, PE_section_name, sizeof(hdr.Name));
  271. hdr.Misc.VirtualSize = PE_virtual_size;
  272. hdr.VirtualAddress = PE_rva - PE_image_base;
  273. hdr.SizeOfRawData = PE_raw_size;
  274. hdr.PointerToRawData = PE_file_offset;
  275. hdr.Characteristics = PE_Characteristics;
  276. fwrite(&hdr, sizeof(hdr), 1, fd);
  277. }

thanks in advance,

vs49688

Member Avatar
Light Poster
48 posts since Dec 2007
Reputation Points: 10
Solved Threads: 1
Skill Endorsements: 0
 
0
 

is nobody going to help. I really need to do this.

Member Avatar
Most Valuable Poster
10,263 posts since Oct 2006
Reputation Points: 4,155
Solved Threads: 416
Skill Endorsements: 22
Moderator
Featured
 
0
 

is nobody going to help. I really need to do this.

My best advice is to contact the original author ( Luigi Auriemma) about this. I'm not going to waste hours of work on this, when the OP (you) isn't showing any effort whatsoever.
Besides: this smells a bit to illegal for my taste

Member Avatar
Newbie Poster
2 posts since Aug 2009
Reputation Points: 10
Solved Threads: 0
Skill Endorsements: 0
 
0
 

Hello,

I've researched the cryptographic algorithm (needed it to fix a bug in hw.dll).

Here goes:

  1. Decryption algorithm:
  2. key = 'W'
  3. for all bytes:
  4. new_byte = byte^key
  5. key += new_byte+'W'
  6. Encryption algorithm:
  7. key = 'W'
  8. for all bytes:
  9. new_byte = byte^key
  10. key += byte^'W'

For people interested in (fixing) the hw.dll bug; it's the bug where, on systems with more than 2147483647 (2^31-1) bytes of RAM, Half-Life exits with the error message "Available memory less than 15MB!!!".

To fix this bug, I decrypted hw.dll, then patched the opcode at offset 0xB5464:

  1. From:
  2. 3D 00 00 F0 00: cmp eax, 0xF00000
  3. A3 B4 14 80 02: mov [0x28014B4], eax
  4. 7D 12: jge 0xB5478 ; Bug. We should ignore the OF (overflow flag).
  5. To:
  6. 3D 00 00 F0 00: cmp eax, 0xF00000
  7. A3 B4 14 80 02: mov [0x28014B4], eax
  8. 73 12: jnb 0xB5478 ; Patched. Ignores the OF (overflow flag).

...and then encrypted the DLL again using the aforementioned algorithm.

I've hosted the encryption/decryption source code for the algorithm over here:
http://my-svn.assembla.com/svn/slipstream/valve_crypt/
(I figure source code is just a description of the inner workings, so as long as I distribute only information instead of binaries, there should be no legal issues.)

Jelle Geerts

You
This article has been dead for over three months: Start a new discussion instead
Post: Markdown Formatting Help
Start New Discussion
High-performance Wi-Fi Solutions For Education. Download A Free Infopack Now.