CovetousEyes

[NODE JS] Add section to PE EXE x86

Feb 6th, 2013
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var fs = require('fs');
  2.  
  3. const PE_DosHeader = 0, PE_NtHeaders = 1, PE_FileHeader = 2, PE_OptionalHeader = 3, PE_SectionHeaders = 4, PE_DataDirectories = 5,
  4. PE_ExportDirectory = 6, PE_ImportDirectory = 7, PE_ResourceDirectory = 8, PE_ExceptionDirectory = 9, PE_SecurityDirectory = 0xa,
  5. PE_RelocationDirectory = 0xb, PE_DebugDirectory = 0xc, PE_TLSDirectory = 0xd, PE_ConfigurationDirectory = 0xe,
  6. PE_BoundImportDirectory = 0xf, PE_ImportAddressTableDirectory = 0x10, PE_DelayImportDirectory = 0x11, PE_DotNETDirectory = 0x12;
  7.  
  8. String.prototype.rtrim = function() {return this.replace(/\0+$/,"");}
  9.  
  10. function toSectionNameBuf(s) {
  11.   var buf = new Buffer(8);
  12.   buf.fill(0);
  13.   if (s.length > 8) s = s.slice(0, 8);
  14.   buf.write(s, 0, s.length, 'ascii');
  15.   return(buf);};
  16.  
  17. function alignBy(v, by) {
  18.  return((v%by)?(1+Math.floor(v/by))*by:v)};
  19.  
  20. function PEFile(){
  21.   this.buf;
  22.   this.peStrucTable;}
  23.                                                                                                                              
  24. PEFile.prototype.OpenPE = function(file) {
  25.   this.buf = fs.readFileSync(file);
  26.   var sig = this.buf.toString('ascii', 0, 2)
  27.   if (sig != 'MZ') return(false);                                                            
  28.   var pHeaderPE = this.buf.readUInt16LE(0x3c);
  29.   if (this.buf.readUInt16LE(pHeaderPE) !== 0x4550) return(false);
  30.   var pDataDirectories = pHeaderPE+0x78;
  31.   this.peStrucTable = [0, pHeaderPE, pHeaderPE+0x4, pHeaderPE+44, pHeaderPE+0xf8, pDataDirectories, pDataDirectories,
  32.     pDataDirectories+0x8, pDataDirectories+0x10, pDataDirectories+0x18, pDataDirectories+0x20, pDataDirectories+0x28,
  33.     pDataDirectories+0x30, pDataDirectories+0x48, pDataDirectories+0x50, pDataDirectories+0x58, pDataDirectories+0x60,
  34.     pDataDirectories+0x68, pDataDirectories+0x70];
  35.   return(true);};                                                  
  36.  
  37. PEFile.prototype.Save = function(name){
  38.   fs.writeFileSync(name, this.buf);};
  39.  
  40. PEFile.prototype.readByte = function(ofs) {
  41.   return(this.buf[ofs]);}
  42.  
  43. PEFile.prototype.readWord = function (ofs) {
  44.   return(this.buf.readUInt16LE(ofs));}
  45.  
  46. PEFile.prototype.readDWord = function (ofs) {
  47.   return(this.buf.readUInt32LE(ofs));}
  48.  
  49. PEFile.prototype.readQWord = function (ofs) {
  50.   return(this.buf.readDoubleLE(ofs));}
  51.  
  52. PEFile.prototype.writeByte = function(ofs, val) {
  53.   this.buf[ofs] = val;}
  54.  
  55. PEFile.prototype.writeWord = function (ofs, val) {
  56.   this.buf.writeUInt16LE(val, ofs);}
  57.  
  58. PEFile.prototype.writeDWord = function (ofs, val) {
  59.   this.buf.writeUInt32LE(val, ofs);}
  60.  
  61. PEFile.prototype.writeQWord = function (ofs, val) {
  62.   this.buf.writeDoubleLE(val, ofs);}
  63.  
  64. PEFile.prototype.getNumberOfSections = function(n){
  65.   return(this.readWord(this.getOffset(PE_FileHeader)+0x2));};
  66.  
  67. PEFile.prototype.getOffset = function(n){
  68.   return(this.peStrucTable[n % 0x13]);};  
  69.  
  70. PEFile.prototype.enumSections = function(fEnumProc, lParam){
  71.   var iSections = this.getNumberOfSections();
  72.   for(var i = 0; i < iSections; i++){
  73.     var pSection = this.getOffset(PE_SectionHeaders) + i*0x28;
  74.     var sName = this.buf.toString('ascii', pSection, pSection+8).rtrim();
  75.     fEnumProc.call(this, i, pSection, sName, lParam);};
  76.   return(true);};
  77.  
  78. PEFile.prototype.findSection = function(sName){
  79.   var pSection = null;
  80.   this.enumSections( function(i, p, s, name) { if (s == name) {pSection = p;} }, sName);
  81.   return(pSection);}
  82.  
  83. PEFile.prototype.dumpSection = function(sName) {
  84.   var dwVirtualSize, dwRawSize, dwRawAddr, bufSection, bufSectionHeader = new Buffer(0x28), pSection = this.findSection(sName);
  85.   if (!pSection) return(null);
  86.   this.buf.copy(bufSectionHeader, 0, pSection, pSection+0x28);
  87.   dwRawSize = bufSectionHeader.readUInt32LE(0x10);
  88.   dwVirtualSize = bufSectionHeader.readUInt32LE(0x8);
  89.   dwRawAddr = bufSectionHeader.readUInt32LE(0x14);
  90.   if (dwRawSize < dwVirtualSize) dwVirtualSize = dwRawSize;
  91.   bufSection = new Buffer(dwVirtualSize);
  92.   this.buf.copy(bufSection, 0, dwRawAddr, dwRawAddr+dwVirtualSize);
  93.   return(bufSection);};
  94.  
  95. PEFile.prototype.addSectionHeader = function(name) {
  96.   var pSectionHeaders = this.getOffset(PE_SectionHeaders), pHeaderOffset = 0x28*this.getNumberOfSections()+pSectionHeaders,
  97.   pFirstSectionData = this.readDWord(pSectionHeaders+0x14);
  98.   if (pFirstSectionData <= pHeaderOffset) return(false);
  99.   this.buf.fill(0, pHeaderOffset, pHeaderOffset+0x28);
  100.   toSectionNameBuf(name).copy(this.buf, pHeaderOffset);
  101.   this.writeDWord(pHeaderOffset+0x24, 0xC0000000);             
  102.   var pSecNum = this.getOffset(PE_FileHeader)+0x2;
  103.   this.writeWord(pSecNum, this.readWord(pSecNum)+1);
  104.   return(true);};
  105.  
  106. PEFile.prototype.addSectionEmpty = function(name, size, ch){
  107.   if (!this.addSectionHeader(name)) return false;
  108.   var pSectionHeaders = this.getOffset(PE_SectionHeaders), iSect = this.getNumberOfSections(),
  109.   dwSectionAligment = this.readDWord(this.getOffset(PE_FileHeader)+0x34),
  110.   dwFileAligment = this.readDWord(this.getOffset(PE_FileHeader)+0x38);
  111.   var pLastSectionHdr = pSectionHeaders+(iSect-2)*0x28;
  112.   var pVA = alignBy(this.readDWord(pLastSectionHdr+0x8), dwSectionAligment)+this.readDWord(pLastSectionHdr+0xC);
  113.   var pRA = alignBy(this.readDWord(pLastSectionHdr+0x10), dwFileAligment)+this.readDWord(pLastSectionHdr+0x14);
  114.   var dwSizeRaw = alignBy(size, dwFileAligment);
  115.   var pNewSectionHdr = pSectionHeaders+(iSect-1)*0x28;
  116.   this.writeDWord(pNewSectionHdr+0x8, size);
  117.   this.writeDWord(pNewSectionHdr+0xC, pVA);
  118.   this.writeDWord(pNewSectionHdr+0x10, dwSizeRaw);
  119.   this.writeDWord(pNewSectionHdr+0x14, pRA);
  120.   var b = new Buffer(dwSizeRaw);
  121.   b.fill(0);
  122.   this.buf = Buffer.concat([this.buf, b]);
  123.   return(true)};
  124.  
  125. PEFile.prototype.addSection = function(name, buf, ch) {
  126.   this.addSectionEmpty(name, buf.length, ch);
  127.   var pLastSecHdr = this.getOffset(PE_SectionHeaders) + (this.getNumberOfSections()-1)*0x28;
  128.   buf.copy(this.buf, this.readDWord(pLastSecHdr+0x14));};  
  129.  
  130. PEFile.prototype.sectionFromRVA = function (rva) {
  131.   var result = null;
  132.   this.enumSections( function(i, p, s, rva){
  133.     var dwVirtualSize = this.readWord(p+0x8), dwVirtualAddress =  this.readWord(p+0xC);
  134.     if (rva >= dwVirtualAddress && rva  < dwVirtualAddress+dwVirtualSize) result = i;}, rva);
  135.   return(result);};
  136.  
  137. PEFile.prototype.rebuildImageSize = function (){
  138.   var  dwSectionAligment = this.readDWord(this.getOffset(PE_FileHeader)+0x34),
  139.   pLastSecHdr = this.getOffset(PE_SectionHeaders) + (this.getNumberOfSections()-1)*0x28;
  140.   var dwSizeImage = alignBy(this.readDWord(pLastSecHdr+0x8), dwSectionAligment)+this.readDWord(pLastSecHdr+0xC);
  141.   this.writeDWord(this.getOffset(PE_FileHeader)+0x4C, dwSizeImage);
  142.   return(true)};
  143.  
  144. var bufX = new Buffer('I LOVE NODE.JS ! \n(c) CovetousEyes', 'ascii');
  145. var pef = new PEFile();
  146. pef.OpenPE('test.EXE');
  147. pef.addSection('.FUNNY', bufX);
  148. pef.rebuildImageSize();
  149. pef.Save('testCracked.exe');
Advertisement
Add Comment
Please, Sign In to add comment