One Function
One Function
Nice Challenge, which disassembler did you use?
I use IDA PRO, but I think it's too complex for me.
I use IDA PRO, but I think it's too complex for me.
- TheBigBoss
- Posts: 29
- Joined: Thu Jun 07, 2012 12:07 pm
- Location: Germany
Because of none x86-64 development tools installed,
I used the following quick and dirty C-code instead.
Please be assured, I am not proud of it...
I used the following quick and dirty C-code instead.
Please be assured, I am not proud of it...
Code: Select all
#include <iostream>
#define DWORD(adr) (*((unsigned long*)&mem[adr]))
#define QWORD(adr) (*((unsigned long long*)&mem[adr]))
int main(int,char**){
char mem[2048];
unsigned rbp=1024;
DWORD(rbp-0x8)=0x77df4777L;
DWORD(rbp-0x4)=0x225fbb61L;
QWORD(rbp-0x10)=0x1993LL;
QWORD(rbp-0x8)+=QWORD(rbp-0x10);
goto loc_3f;
loc_24:
QWORD(rbp-0x8)-=0x6b2896a8LL;
QWORD(rbp-0x8)^=0x2232c968b04dab36LL;
QWORD(rbp-0x10)--;
loc_3f:
if(QWORD(rbp-0x10))goto loc_24;
std::cout<<QWORD(rbp-0x8);
return 0;
}
Just execute the binary!
(The solution check seems to be broken currently, however.)
Code: Select all
#include <stdio.h>
int main() {
unsigned long (*code)(void) = "\x55\x48\x89\xe5\xc7\x45\xf8\x77\x47\xdf\x77\xc\7\x45\xfc\x61\xbb\x5f\x22\x48\xc7\x45\xf0\x93\x19\x00\x00\x48\x8b\x45\xf0\x48\x\01\x45\xf8\xeb\x1b\x48\x81\x6d\xf8\xa8\x96\x28\x6b\x48\xb8\x36\xab\x4d\xb0\x68\\xc9\x32\x22\x48\x31\x45\xf8\x48\x83\x6d\xf0\x01\x48\x83\x7d\xf0\x00\x75\xde\x48\\x8b\x45\xf8\xc9\xc3";
printf("%lu\n", code());
}
Disassembling the thing in 32-bit mode resulted in way more intricate (valid!) code:
- it ate stack in loop ('push dword 0x482232c9')
- had useless instructions ('dec eax')
- rewrote local arguments (I thought it's the real trick for this challenge)
- and produced 4-byte "O..k" string (after dealing with stack)
After failing on 32-bit disassembly I've switched to 64-bit which was relatively boring.
Question to challenge author:
did you intentionally made it 32-bit compatible with such nontrivial effects
or it's just a coincidence?
Really nice challenge! It was fun to hack on.
Thanks!
- it ate stack in loop ('push dword 0x482232c9')
- had useless instructions ('dec eax')
- rewrote local arguments (I thought it's the real trick for this challenge)
- and produced 4-byte "O..k" string (after dealing with stack)
After failing on 32-bit disassembly I've switched to 64-bit which was relatively boring.
Question to challenge author:
did you intentionally made it 32-bit compatible with such nontrivial effects
or it's just a coincidence?
Really nice challenge! It was fun to hack on.
Thanks!
As much as I would like to claim this was intentional, I think it is just a coincidence. If I recall basic x86 instructions in 16,32 & 64bit are essentially the same (it just depends on the processor mode), and I think there would only be one or two places where the instructions take immediate values which would be where disassembly gets messed up. I don't think it's too unlikely in a small sample of code that it can be disassembled in more than one mode, as long as it doesn't have too many random immediate values.
I have used
http://www.onlinedisassembler.com/odaweb/
First try was i386, but the dec eax looked wierd. The i386:x64 looked much better.
I have written easy equivalent in java to look at the resulting long ...
http://www.onlinedisassembler.com/odaweb/
First try was i386, but the dec eax looked wierd. The i386:x64 looked much better.
I have written easy equivalent in java to look at the resulting long ...
After disassambling it with ndisasm, and a few failed attempts of rewriting it in C I just followed the old reverse engineering technique: "Just run it, but beware that it might be a malware"
* slap the main and jmp labels to the disassambled code
* recompile with nasm using elf64
* link with ld
* run in debug mode using gdb
* inspect rax and decode the hex
* slap the main and jmp labels to the disassambled code
* recompile with nasm using elf64
* link with ld
* run in debug mode using gdb
* inspect rax and decode the hex
If it works, it's obsolete !