One Function

Discussion of challenges you have already solved
Post Reply
User avatar
MatRush
Posts: 33
Joined: Fri May 13, 2011 1:26 pm
Location: China
Contact:

One Function

Post by MatRush »

Nice Challenge, which disassembler did you use?
I use IDA PRO, but I think it's too complex for me.
User avatar
MatRush
Posts: 33
Joined: Fri May 13, 2011 1:26 pm
Location: China
Contact:

Post by MatRush »

Or there is any tools can run the 64bit asm code?
User avatar
CodeX
Posts: 350
Joined: Fri Oct 17, 2008 5:28 pm

Post by CodeX »

One way to solve this by running it is so execute it on a x86-64 processor e.g. put the function into a char[] in C and then call it using a function pointer. NASM can disassemble the code which is what I used for testing this.
ctzsm
Posts: 3
Joined: Fri Jan 27, 2012 5:59 am

Post by ctzsm »

CodeX wrote:One way to solve this by running it is so execute it on a x86-64 processor e.g. put the function into a char[] in C and then call it using a function pointer. NASM can disassemble the code which is what I used for testing this.
That's awesome!
User avatar
TheBigBoss
Posts: 29
Joined: Thu Jun 07, 2012 12:07 pm
Location: Germany

Post by TheBigBoss »

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...

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;
}
chris2
Posts: 2
Joined: Wed Aug 17, 2011 8:07 pm

Post by chris2 »

Just execute the binary!

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());
}
(The solution check seems to be broken currently, however.)
trofi
Posts: 23
Joined: Mon Oct 14, 2013 7:20 pm

Post by trofi »

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!
User avatar
CodeX
Posts: 350
Joined: Fri Oct 17, 2008 5:28 pm

Post by CodeX »

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.
User avatar
Hippo
Posts: 339
Joined: Sat Feb 01, 2014 12:05 am
Location: Praha 5

Post by Hippo »

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 ...
User avatar
yes-man
Posts: 32
Joined: Fri Jan 30, 2009 5:14 pm

Post by yes-man »

Like other before me, I looked at the x86 output and said 'strange'. Then I tried the x64 one and it looked much better. After a bit of ASM reading and thinking (together with vralfy), we figured out what the code was doing and coded it in #C (and PHP).

Great challenge. Liked it :D
helly0d
Posts: 29
Joined: Fri Feb 13, 2009 2:10 am
Location: Iasi Romania

Post by helly0d »

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
If it works, it's obsolete !
Post Reply