Welcome to the new Woodmann RCE Messageboards Regroupment
Please be patient while the rest of the site is restored.

To all Members of the old RCE Forums:
In order to log in, it will be necessary to reset your forum login password ("I forgot my password") using the original email address you registered with. You will be sent an email with a link to reset your password for that member account.

The old vBulletin forum was converted to phpBB format, requiring the passwords to be reset. If this is a problem for some because of a forgotten email address, please feel free to re-register with a new username. We are happy to welcome old and new members back to the forums! Thanks.

All new accounts are manually activated before you can post. Any questions can be PM'ed to Kayaker.

snippet [NODE.JS] Add section to PE EXE x86

A classroom run by newbies for newbies. Gain valuable reversing experience & skills as we explain the in's and out's of RCE.

snippet [NODE.JS] Add section to PE EXE x86

Post by CovetousEyes »

Hi! I love Node JS and Reverse Engeneering, so I created code what unite this ones. This NODE.JS snippet added section to PE EXE x86. Maybe code has bugs, but now this module in developing.

Code: Select all

var fs = require('fs');

const PE_DosHeader = 0, PE_NtHeaders = 1, PE_FileHeader = 2, PE_OptionalHeader = 3, PE_SectionHeaders = 4, PE_DataDirectories = 5,
PE_ExportDirectory = 6, PE_ImportDirectory = 7, PE_ResourceDirectory = 8, PE_ExceptionDirectory = 9, PE_SecurityDirectory = 0xa,
PE_RelocationDirectory = 0xb, PE_DebugDirectory = 0xc, PE_TLSDirectory = 0xd, PE_ConfigurationDirectory = 0xe,
PE_BoundImportDirectory = 0xf, PE_ImportAddressTableDirectory = 0x10, PE_DelayImportDirectory = 0x11, PE_DotNETDirectory = 0x12;

String.prototype.rtrim = function() {return this.replace(/\0+$/,"");}

function toSectionNameBuf(s) {
  var buf = new Buffer(8);
  if (s.length > 8) s = s.slice(0, 8);
  buf.write(s, 0, s.length, 'ascii');

function alignBy(v, by) {

function PEFile(){
PEFile.prototype.OpenPE = function(file) {
  this.buf = fs.readFileSync(file);
  var sig = this.buf.toString('ascii', 0, 2)
  if (sig != 'MZ') return(false);                                                            
  var pHeaderPE = this.buf.readUInt16LE(0x3c);
  if (this.buf.readUInt16LE(pHeaderPE) !== 0x4550) return(false);
  var pDataDirectories = pHeaderPE+0x78;
  this.peStrucTable = [0, pHeaderPE, pHeaderPE+0x4, pHeaderPE+44, pHeaderPE+0xf8, pDataDirectories, pDataDirectories,
    pDataDirectories+0x8, pDataDirectories+0x10, pDataDirectories+0x18, pDataDirectories+0x20, pDataDirectories+0x28,
    pDataDirectories+0x30, pDataDirectories+0x48, pDataDirectories+0x50, pDataDirectories+0x58, pDataDirectories+0x60, 
    pDataDirectories+0x68, pDataDirectories+0x70]; 

PEFile.prototype.Save = function(name){
  fs.writeFileSync(name, this.buf);};

PEFile.prototype.readByte = function(ofs) {

PEFile.prototype.readWord = function (ofs) {

PEFile.prototype.readDWord = function (ofs) {

PEFile.prototype.readQWord = function (ofs) {

PEFile.prototype.writeByte = function(ofs, val) {
  this.buf[ofs] = val;}

PEFile.prototype.writeWord = function (ofs, val) {
  this.buf.writeUInt16LE(val, ofs);}

PEFile.prototype.writeDWord = function (ofs, val) {
  this.buf.writeUInt32LE(val, ofs);}

PEFile.prototype.writeQWord = function (ofs, val) {
  this.buf.writeDoubleLE(val, ofs);}
PEFile.prototype.getNumberOfSections = function(n){

PEFile.prototype.getOffset = function(n){
  return(this.peStrucTable[n % 0x13]);};  

PEFile.prototype.enumSections = function(fEnumProc, lParam){
  var iSections = this.getNumberOfSections();
  for(var i = 0; i < iSections; i++){
    var pSection = this.getOffset(PE_SectionHeaders) + i*0x28;
    var sName = this.buf.toString('ascii', pSection, pSection+8).rtrim();
    fEnumProc.call(this, i, pSection, sName, lParam);};

PEFile.prototype.findSection = function(sName){
  var pSection = null;
  this.enumSections( function(i, p, s, name) { if (s == name) {pSection = p;} }, sName);

PEFile.prototype.dumpSection = function(sName) {
  var dwVirtualSize, dwRawSize, dwRawAddr, bufSection, bufSectionHeader = new Buffer(0x28), pSection = this.findSection(sName);
  if (!pSection) return(null);
  this.buf.copy(bufSectionHeader, 0, pSection, pSection+0x28);
  dwRawSize = bufSectionHeader.readUInt32LE(0x10);
  dwVirtualSize = bufSectionHeader.readUInt32LE(0x8);
  dwRawAddr = bufSectionHeader.readUInt32LE(0x14);
  if (dwRawSize < dwVirtualSize) dwVirtualSize = dwRawSize;
  bufSection = new Buffer(dwVirtualSize);
  this.buf.copy(bufSection, 0, dwRawAddr, dwRawAddr+dwVirtualSize);

PEFile.prototype.addSectionHeader = function(name) {
  var pSectionHeaders = this.getOffset(PE_SectionHeaders), pHeaderOffset = 0x28*this.getNumberOfSections()+pSectionHeaders,
  pFirstSectionData = this.readDWord(pSectionHeaders+0x14);
  if (pFirstSectionData <= pHeaderOffset) return(false);
  this.buf.fill(0, pHeaderOffset, pHeaderOffset+0x28);
  toSectionNameBuf(name).copy(this.buf, pHeaderOffset);
  this.writeDWord(pHeaderOffset+0x24, 0xC0000000);          	
  var pSecNum = this.getOffset(PE_FileHeader)+0x2;
  this.writeWord(pSecNum, this.readWord(pSecNum)+1);

PEFile.prototype.addSectionEmpty = function(name, size, ch){
  if (!this.addSectionHeader(name)) return false;
  var pSectionHeaders = this.getOffset(PE_SectionHeaders), iSect = this.getNumberOfSections(),
  dwSectionAligment = this.readDWord(this.getOffset(PE_FileHeader)+0x34), 
  dwFileAligment = this.readDWord(this.getOffset(PE_FileHeader)+0x38);
  var pLastSectionHdr = pSectionHeaders+(iSect-2)*0x28;
  var pVA = alignBy(this.readDWord(pLastSectionHdr+0x8), dwSectionAligment)+this.readDWord(pLastSectionHdr+0xC);
  var pRA = alignBy(this.readDWord(pLastSectionHdr+0x10), dwFileAligment)+this.readDWord(pLastSectionHdr+0x14);
  var dwSizeRaw = alignBy(size, dwFileAligment);
  var pNewSectionHdr = pSectionHeaders+(iSect-1)*0x28;
  this.writeDWord(pNewSectionHdr+0x8, size);
  this.writeDWord(pNewSectionHdr+0xC, pVA);
  this.writeDWord(pNewSectionHdr+0x10, dwSizeRaw);
  this.writeDWord(pNewSectionHdr+0x14, pRA);
  var b = new Buffer(dwSizeRaw);
  this.buf = Buffer.concat([this.buf, b]);

PEFile.prototype.addSection = function(name, buf, ch) {
  this.addSectionEmpty(name, buf.length, ch);
  var pLastSecHdr = this.getOffset(PE_SectionHeaders) + (this.getNumberOfSections()-1)*0x28; 
  buf.copy(this.buf, this.readDWord(pLastSecHdr+0x14));};  

PEFile.prototype.sectionFromRVA = function (rva) {
  var result = null;
  this.enumSections( function(i, p, s, rva){
    var dwVirtualSize = this.readWord(p+0x8), dwVirtualAddress =  this.readWord(p+0xC);
    if (rva >= dwVirtualAddress && rva  < dwVirtualAddress+dwVirtualSize) result = i;}, rva);

PEFile.prototype.rebuildImageSize = function (){
  var  dwSectionAligment = this.readDWord(this.getOffset(PE_FileHeader)+0x34), 
  pLastSecHdr = this.getOffset(PE_SectionHeaders) + (this.getNumberOfSections()-1)*0x28;
  var dwSizeImage = alignBy(this.readDWord(pLastSecHdr+0x8), dwSectionAligment)+this.readDWord(pLastSecHdr+0xC);
  this.writeDWord(this.getOffset(PE_FileHeader)+0x4C, dwSizeImage);

var bufX = new Buffer('I LOVE NODE.JS ! \n(c) CovetousEyes', 'ascii');
var pef = new PEFile();
pef.addSection('.FUNNY', bufX);
(2.79 KiB) Downloaded 97 times
Posts: 54
Joined: Sun Sep 14, 2008 3:25 pm

Post by aqrit »

This is kinda neat.

Is it possible to create a signature scanner by abusing regex?