Simple Code Injection into ELF Executable
Source: Dev.to
Example Source
/**
* Simple Code Injection
*/
#include
#include
#include
int main(int argc, char *argv[])
{
int i, num;
num = 10;
for (i = 0; i :
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 48 83 ec 20 sub $0x20,%rsp
1155: 89 7d ec mov %edi,-0x14(%rbp)
1158: 48 89 75 e0 mov %rsi,-0x20(%rbp)
115c: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
1163: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
116a: eb 1d jmp 1189
116c: 8b 45 f8 mov -0x8(%rbp),%eax
116f: 89 c6 mov %eax,%esi
1171: 48 8d 05 8c 0e 00 00 lea 0xe8c(%rip),%rax # 2004
1178: 48 89 c7 mov %rax,%rdi
117b: b8 00 00 00 00 mov $0x0,%eax
1180: e8 cb fe ff ff call 1050
1185: 83 45 f8 01 addl $0x1,-0x8(%rbp)
1189: 8b 45 f8 mov -0x8(%rbp),%eax
118c: 3b 45 fc cmp -0x4(%rbp),%eax
118f: 7c db jl 116c
1191: b8 00 00 00 00 mov $0x0,%eax
1196: c9 leave
1197: c3 ret
Identifying the Instruction to Change
The instruction that sets num = 10 is:
c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
c7– opcode formovlwith a 32‑bit immediate.45 fc– displacement-0x4(%rbp).0a 00 00 00– immediate value0x0a(10) in little‑endian order.
The opcode starts at address 0x115c; the immediate byte 0x0a is at 0x115f.
Modifying the Binary
Edit the executable with a hex editor and replace the byte at 0x115f (0x0a) with 0x05:
$ hexedit ./main
Navigate to offset 0x115f, change the value, save, and exit.
Result
Running the patched binary:
$ ./main
Produces:
#0
#1
#2
#3
#4
The program now loops only five times, demonstrating a simple code injection by directly modifying the machine code in an ELF executable.
Note: This technique works only when you replace bytes without altering the overall layout of the binary. Changing instruction lengths or relocating code requires more advanced methods, which are covered in a subsequent article.