Skip to content

Instantly share code, notes, and snippets.

Created November 8, 2014 19:39
Show Gist options
  • Save anonymous/e486705dc16c3a687d3f to your computer and use it in GitHub Desktop.
Save anonymous/e486705dc16c3a687d3f to your computer and use it in GitHub Desktop.
Self modifying code
// Self Modifying Code - Just for fun
//
// Created by Osman Azam on 3/22/14.
// Copyright (c) 2014 Osman Azam. All rights reserved.
//
// This code was tested on OSX. It will probably work in most *NIX systems.
// For windows you will need to find the win32 equivalent of mprotect and
// use a different method of putting the addTwoNumbers function into a data
// section. Also you will need to convert the inline assemblye from AT&T style
// to Intel style
#include <stdio.h>
#include <sys/mman.h>
#include <stdint.h>
#include <string.h>
/* Linkers are type agnostic. They just see symbols.
I am "tricking" the compiler into interpreting instructions
as an array of bytes */
extern uint8_t add_instr[];
extern uint8_t sub_instr[];
extern uint8_t end_of_add[]; // This symbol points to the end of the
// add instruction. Since x86 uses variable
// length instructions I need a way to get
// the length of the instruction. Also
// it is assumed that the add and subtract
// instructions use the same number of bytes
/* The following line of inline assembly creates the subtract instruction
that I'm going to inject into my addTwoNumbers function below */
__asm("_sub_instr: subl %esi, -4(%rbp)");
/* The attribute places this function in the .data section instead of the
.text section. This allows me to write to the function since .text
regions are not normally writable on modern OS's for security reasons
*/
int addTwoNumbers(int a, int b) __attribute__((section(".data,.data")));
int main(int argc, const char * argv[])
{
// Call to mprotect required because modern OS's don't let you write
// to code sections.
mprotect(addTwoNumbers, 1024, PROT_EXEC | PROT_WRITE | PROT_READ);
int x = addTwoNumbers(5, 2);
/* Replace add isntruction with substract instruction */
memcpy(add_instr, sub_instr, end_of_add - add_instr);
int y = addTwoNumbers(5, 2);
printf("%d %d\n", x, y);
return 0;
}
int addTwoNumbers(int a, int b)
{
__asm volatile("_add_instr: addl %1, %0" : "=m"(a): "r"(b) : "memory");
__asm volatile("_end_of_add:");
return a;
}
//Final output should be: 7 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment