1
ASM / Again, selfmodifying asm
« on: October 07, 2006 »
Ok, here I am again, talking about how much i like selfmodifying code segments 
I have a bunch of sourcecodes in asm that uses this technique so save those extra bytes.
But i ran into problem when i wanted to use that code in my c-project.
This is because when i link my asm - i tell the linker to make my exe's code section READ/WRITE/EXECUTABLE
I couldnt find anyway to do this with my c compiler - and i didnt have the heart to do the asm code non-self-modifying (it would have cost me bytes!)
So i wrote this application to help me out. It takes 2 parameters: <filename> and <section-name-to-modify>
It opens the exe file (PE), and locates the section, and change permisions in it, so it will run with my asm code without crashing.
Here are the src for the program (if you wish to use any other permisions than mine). Precompiled exe: (changes to READ/WRITE/EXECUTABLE)
http://www.hd.chalmers.se/~Saida/dbf/section_perm.exe
I wasnt sure this was the right place to put this post, but we have been talking alot about stuff like this here lately .. so.. well. cheers!

I have a bunch of sourcecodes in asm that uses this technique so save those extra bytes.
But i ran into problem when i wanted to use that code in my c-project.
This is because when i link my asm - i tell the linker to make my exe's code section READ/WRITE/EXECUTABLE
I couldnt find anyway to do this with my c compiler - and i didnt have the heart to do the asm code non-self-modifying (it would have cost me bytes!)
So i wrote this application to help me out. It takes 2 parameters: <filename> and <section-name-to-modify>
It opens the exe file (PE), and locates the section, and change permisions in it, so it will run with my asm code without crashing.
Here are the src for the program (if you wish to use any other permisions than mine). Precompiled exe: (changes to READ/WRITE/EXECUTABLE)
http://www.hd.chalmers.se/~Saida/dbf/section_perm.exe
Code: [Select]
/**
* PE header section permision modifier.
* Will set the section to READ/WRITE/EXECUTE
* usable if you wrote a selfmodifying code segment in asm, and wishes
* to use that outputed asm obj in you c program.
* - Add this in a .bat file after you compiled your c project into a exe.
* (only PE format supported)
*
* code by saida^titan^rebels
* 2006-10-06
* saida@lava.nu
* http://saida.lava.nu
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void showReadError()
{
printf("*** Could not read from file - is it a valid PE?\n");
}
void showWriteError()
{
printf("*** Could not write to file - in use - or disk full?\n");
}
void showUsage()
{
printf("Usage: section_perm.exe <filename> <section name to alter>\n");
}
void showOpenError()
{
printf("Could not open input file\n");
}
int main(int argc, char *argv[])
{
//section to modify
IMAGE_SECTION_HEADER modSection;
IMAGE_DOS_HEADER headerDos;
IMAGE_FILE_HEADER headerPE;
int i;
HFILE hFile;
unsigned char cBuf [5];
long sectionStartAddr;
if (argc<3) {
showUsage();
return 0;
}
// open file
hFile = _lopen(argv[1], OF_READWRITE);
if (hFile==0) {
showOpenError();
return 0;
}
//write some text on start.
printf("--------------------------------------------------------------------------------");
printf("*** Starting section_perm.exe\n");
printf("*** Opening file: \"%s\" and searching for \"%s\"\n", argv[1], argv[2]);
//read dos header and check we read the correct amount of bytes
if (_lread(hFile, &headerDos, sizeof(IMAGE_DOS_HEADER))!=sizeof(IMAGE_DOS_HEADER)) {
printf("DOS_HEADER: ");
showReadError();
return 0;
}
//move filepointer to PE header start...
_llseek(hFile, headerDos.e_lfanew, FILE_BEGIN);
// Read PE signature and check we read the correct amount of bytes
memset(&cBuf, 0, 5);
if (_lread(hFile, &cBuf, 4)!=4) {
printf("PE_HEADER_SIGNATURE: ");
showReadError();
return 0;
}
// check read data to make sure this is a PE file
if (strcmp("PE", cBuf)!=0) {
printf("PE signature not found. This is not av valid PE file!");
return 0;
}
//read PE header data
if (_lread(hFile, &headerPE, sizeof(IMAGE_FILE_HEADER))!=sizeof(IMAGE_FILE_HEADER)) {
printf("PE_HEADER: ");
showReadError();
return 0;
}
//move pass the optional header
_llseek(hFile, headerPE.SizeOfOptionalHeader, FILE_CURRENT );
//now, we are on the first section address.
sectionStartAddr = headerDos.e_lfanew + sizeof(IMAGE_FILE_HEADER) + headerPE.SizeOfOptionalHeader + 4;
// step through all sections and search for the section the user entered.
for (i=0; i < headerPE.NumberOfSections; i++) {
if (_lread(hFile, &modSection, sizeof(IMAGE_SECTION_HEADER))!=sizeof(IMAGE_SECTION_HEADER)) {
printf("SECTION: ");
showReadError();
break;
}
// print current section
printf("%d: %s\n",i, modSection.Name);
if (strcmp(argv[2], modSection.Name)==0) {
modSection.Characteristics = modSection.Characteristics | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
_llseek(hFile, sectionStartAddr + (i * sizeof(IMAGE_SECTION_HEADER)), FILE_BEGIN);
if (_lwrite(hFile, &modSection, sizeof(IMAGE_SECTION_HEADER))==HFILE_ERROR) {
printf("SECTION: ");
showWriteError();
} else {
printf("Section was found and written to.\n" );
}
_lclose(hFile);
return 0;
}
}
// close the exe file
_lclose(hFile);
printf("Section was not found in file. Did you forget the leading dot?\n");
return 0;
}
I wasnt sure this was the right place to put this post, but we have been talking alot about stuff like this here lately .. so.. well. cheers!


/