Closed AdamVanScyoc closed 3 years ago
I encountered the same error when trying out RetroWrite on a very simple piece of code and have not yet been able to figure it out. My sample piece of code is this:
#include <stdio.h>
int main(){
int y = 10;
int x = 12 + y;
printf("result is %i\n", x);
}
I recompiled in exactly the same way and got the same error.
Interestingly the error did not occur when I commented out the line containing printf
.
I ran to the executable with GDB to check which instruction caused the exception i.e.
gdb a.out
run
x/i $pc
This is the GDB output
Program received signal SIGILL, Illegal instruction.
0x0000555555555050 in _start ()
(gdb) x/i $pc
=> 0x555555555050 <_start+16>: lock push %rax
(gdb)
I have inspected the generated binary further and I found that the call to printf
seems to point to the wrong address.
0x1151 <main+33>: lea 0xeb0(%rip),%rdi # 0x2008
0x1158 <main+40>: mov $0x0,%eax
0x115d <main+45>: callq 0x1050 <_start+16>
0x1162 <main+50>: mov $0x0,%eax
0x1167 <main+55>: leaveq
0x1168 <main+56>: retq
The instruction callq
jumps to <_start+16> which then triggers the illegal instruction error.
I also inspected the assembly generated by retrowrite and it also contains the instruction.
Maybe this call is not position independent? Or does RetroWrite not support using stdlib functions?
@AdamVanScyoc I noticed that in the demo the devs provided they use clang instead of GCC, and compiling with clang instead of GCC seemed to fix the issue for me.
For reference, call you post the corresponding code sections before/after RetroWrite symbolized them?
FYI: I'm having a hard time reproducing your issue :/
gannimo@apidae:~/repos/RetroWrite/x{0}$ wget https://github.com/CUCyber/cuctf-2020-challenges/raw/main/reverse-engineering/virtual/virtual.c
--2021-01-10 21:15:06-- https://github.com/CUCyber/cuctf-2020-challenges/raw/main/reverse-engineering/virtual/virtual.c
Resolving github.com (github.com)... 140.82.121.4
Connecting to github.com (github.com)|140.82.121.4|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/CUCyber/cuctf-2020-challenges/main/reverse-engineering/virtual/virtual.c [following]
--2021-01-10 21:15:06-- https://raw.githubusercontent.com/CUCyber/cuctf-2020-challenges/main/reverse-engineering/virtual/virtual.c
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.240.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.240.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6015 (5.9K) [text/plain]
Saving to: ‘virtual.c’
virtual.c 100%[===============================================================>] 5.87K --.-KB/s in 0s
2021-01-10 21:15:07 (32.1 MB/s) - ‘virtual.c’ saved [6015/6015]
gannimo@apidae:~/repos/RetroWrite/x{0}$ gcc virtual.c -O0 -ggdb -Wall -Wpedantic -Wextra -fPIC -fPIE -pie -o virtual_pie
virtual.c: In function ‘vm’:
virtual.c:50:5: warning: ISO C forbids nested functions [-Wpedantic]
void push(int v)
^~~~
virtual.c:54:5: warning: ISO C forbids nested functions [-Wpedantic]
int pop()
^~~
virtual.c:70:5: warning: ISO C forbids nested functions [-Wpedantic]
int fetch()
^~~
virtual.c:84:5: warning: ISO C forbids nested functions [-Wpedantic]
void decode(int bc)
^~~~
virtual.c:94:5: warning: ISO C forbids nested functions [-Wpedantic]
void eval()
^~~~
virtual.c:217:5: warning: ISO C forbids nested functions [-Wpedantic]
void run()
^~~~
virtual.c:83:41: warning: variable ‘reg3’ set but not used [-Wunused-but-set-variable]
int instr=0, imm=0, reg1=0, reg2=0, reg3=0, tmp1=0, tmp2=0;
^~~~
virtual.c:83:33: warning: variable ‘reg2’ set but not used [-Wunused-but-set-variable]
int instr=0, imm=0, reg1=0, reg2=0, reg3=0, tmp1=0, tmp2=0;
^~~~
virtual.c: In function ‘main’:
virtual.c:236:20: warning: variable ‘z’ set but not used [-Wunused-but-set-variable]
void *y[128], *z[128];
^
virtual.c:236:11: warning: variable ‘y’ set but not used [-Wunused-but-set-variable]
void *y[128], *z[128];
^
gannimo@apidae:~/repos/RetroWrite/x{0}$ ../retrowrite virtual_pie virtual.s
[*] Relocations for a section that's not loaded: .rela.dyn
[*] Relocations for a section that's not loaded: .rela.plt
[x] Could not replace value in .init_array
[x] Couldn't find valid section 3df0
[x] Couldn't find valid section 3fd8
[x] Couldn't find valid section 3fe0
[x] Couldn't find valid section 3fe8
[x] Couldn't find valid section 3ff0
[x] Couldn't find valid section 3ff8
gannimo@apidae:~/repos/RetroWrite/x{0}$ gcc virtual.s
gannimo@apidae:~/repos/RetroWrite/x{0}$ ./a.out
Enter Password:
asdf
Incorrect.
gannimo@apidae:~/repos/RetroWrite/x{0}$
gannimo@apidae:~/repos/RetroWrite/x{0}$ gcc --version
gcc (Debian 8.3.0-6) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
So with the most current Ubuntu docker image and gcc 8.4 installed through Apt, I am able to get to compile, but all the stdio.h functions don't seem to work. When modifying virtual.c in order to get it to compile with clang, I am able to get it to compile and run correctly.
(retro) root@916cb7ed4b8e:/src# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.1 LTS
Release: 20.04
Codename: focal
(retro) root@916cb7ed4b8e:/src# gcc-8 --version
gcc-8 (Ubuntu 8.4.0-3ubuntu2) 8.4.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
(retro) root@916cb7ed4b8e:/src# python3 --version
Python 3.8.5
Here's running the working version (before retrowriting with retrowrite virtual_no_pie virtual_no_pie.s
) and the non-working version (after re-compiling/re-assembling with gcc 8.4 gcc-8 virtual_no_pie.s -o virtual_retro
):
(retro) root@916cb7ed4b8e:/src# ./virtual_no_pie
Enter Password:
asdasd
Incorrect.
(retro) root@916cb7ed4b8e:/src# ./virtual_retro
(retro) root@916cb7ed4b8e:/src#
Note that none of ./virtual_retro
's puts()
or fgets()
calls are working.
This is a bit of a non-issue since it works with clang, and worked for you with gcc 8.3. But it probably relates to #19 so I thought that maybe it'd be useful info. If not I'm OK with closing this issue, up to you
Thanks again
After some investigation, it looks like retrowrite did not parse the .plt section generated by old gcc (such as 8.4) I recently pushed a fix, it should now work even there. Recent gcc compilers do not have this problem.
Closing this issue, feel free to reopen if it's still not working.
Hello, thanks for retrowrite - I enjoyed your 36c3 presentation.
I installed retrowrite in a fresh Ubuntu docker container:
... and followed the indicated setup steps by running the startup script
setup.sh
and created a virtual environment. Presumably this installed the correct version of capstone, and there doesn't appear to be a different capstone version installed through APT.I have an x86_64 ELF that was a CTF challenge ( https://github.com/CUCyber/cuctf-2020-challenges/blob/main/reverse-engineering/virtual/virtual.c ) that I'm attempting to rewrite, but when I execute the re-written and re-compiled binary, I get an Illegal Instruction signal.
I compiled virtual.c with
gcc virtual.c -O0 -ggdb -Wall -Wpedantic -Wextra -fPIC -fPIE -pie -o virtual_pie
(ignore the makefile that's in the linked github repo), confirmed that this executable runs without error, and re-wrote with:/retrowrite/retrowrite virtual_pie virtual_pie.s
Next, I re-compiled with:
gcc virtual_pie.s -o virtual_pie_retro
Now when I try to run the executable, I get:
Any ideas? Thanks again