How to get Radare2 to use symbol table information for library calls? - c

Objdump can figure out when the binary is calling GLIBC functions, like printf:
$ objdump -d crackme03.64 -Mintel | grep printf
5c8: ff 25 12 0a 20 00 jmp QWORD PTR [rip+0x200a12] #200fe0 <__printf_chk#GLIBC_2.3.4>
However, looking at the same address, Radare is much less helpful:
[0x000005c8]> pd 2
/ (fcn) sub.__cxa_finalize_224_5c8 8
| sub.__cxa_finalize_224_5c8 ();
| ; CALL XREF from 0x000007bc (sym.main)
| ; CALL XREF from 0x00000809 (sym.main)
| 0x000005c8 ff25120a2000 jmp qword [reloc.__cxa_finalize_224] ; [0x200fe0:8]=0 LEA reloc.__cxa_finalize_224 ; reloc.__cxa_finalize_224
\ 0x000005ce 6690 nop
Is there a way to ask Radare to figure out what these functions correspond to?

It should work if you're using the newest version from git.
Radare2’s development is pretty quick – the project evolves every day, therefore it’s recommended to use the current git version. Update your version and it should solve your problem:
$ git clone https://github.com/radare/radare2.git
$ cd radare2
$ ./sys/install.sh

Related

Aarch64 baremetal Hello World program on QEMU

I have compiled and ran a simple hello world program on ARM Foundation Platform. The code is given below.
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello world!\n");
return 0;
}
This program is compiled and linked using ARM GNU tool chain as given below.
$aarch64-none-elf-gcc -c -march=armv8-a -g hello.c hello.o
aarch64-none-elf-gcc: warning: hello.o: linker input file unused because linking not done
$aarch64-none-elf-gcc -specs=aem-ve.specs -Wl,-Map=linkmap.txt hello.o -o hello.axf
I could successfully execute this program on ARM Foundation Platform (I think, foundation platform is similar to ARM Fixed Virtual Platform) and it prints "Hello world!"
The contents of 'aem-ve.specs' file is given below:
cat ./aarch64-none-elf/lib/aem-ve.specs
# aem-ve.specs
#
# Spec file for AArch64 baremetal newlib, libgloss on VE platform with version 2
# of AngelAPI semi-hosting.
#
# This Spec file is also appropriate for the foundation model.
%rename link old_link
*link:
-Ttext-segment 0x80000000 %(old_link)
%rename lib libc
*libgloss:
-lrdimon
*lib:
cpu-init/rdimon-aem-el3.o%s --start-group %(libc) %(libgloss) --end-group
*startfile:
crti%O%s crtbegin%O%s %{!pg:rdimon-crt0%O%s} %{pg:rdimon-crt0%O%s}
Is it possible to execute the same binary on QEMU? If so could you please share the sample command. If not, could you please share the right and best way to execute it on QEMU?
I have traced instruction execution of Foundation platform using the "trace" option and analysed using 'tarmac-profile' tool and 'Tarmac-calltree' tool. The outputs are given below:
$ ./tarmac-profile hello.trace --image hello.axf
Address Count Time Function name
0x80000000 1 120001
0x80001030 1 30001 register_fini
0x80001050 1 60001 deregister_tm_clones
0x800010c0 1 210001 __do_global_dtors_aux
0x80001148 1 23500001 frame_dummy
0x800012c0 1 10480001 main
0x80002000 1 40001 main
0x80003784 1 360001 main
0x80003818 1 460001 _cpu_init_hook
0x80003870 1 590001 _write_r
0x800038d0 1 1090001 __call_exitprocs
...
...
./tarmac-calltree hello.trace --image hello.axf
o t:10000 l:2288 pc:0x80001148 - t:23510000 l:7819 pc:0x80008060 : frame_dummy
- t:240000 l:2338 pc:0x800011a8 - t:720000 l:2443 pc:0x800011ac
o t:250000 l:2340 pc:0x80003818 - t:710000 l:2442 pc:0x80003828 : _cpu_init_hook
- t:260000 l:2343 pc:0x8000381c - t:320000 l:2354 pc:0x80003820
o t:270000 l:2345 pc:0x80002000 - t:310000 l:2353 pc:0x80002010 : main
- t:320000 l:2354 pc:0x80003820 - t:700000 l:2436 pc:0x80003824
o t:330000 l:2356 pc:0x80003784 - t:690000 l:2435 pc:0x80003814 : main
- t:760000 l:2453 pc:0x800011bc - t:2010000 l:2970 pc:0x800011c0
o t:770000 l:2455 pc:0x80004200 - t:2000000 l:2969 pc:0x800042c0 : memset
- t:2010000 l:2970 pc:0x800011c0 - t:4870000 l:3587 pc:0x800011c4
o t:2020000 l:2972 pc:0x80007970 - t:4860000 l:3586 pc:0x80007b04 : initialise_monitor_handles
- t:2960000 l:3165 pc:0x80007b24 - t:4340000 l:3465 pc:0x80007b28
I have tried the following method to execute on QEMU, without any success.
I have started the QEMU with gdb based debugging through TCP Port
$ qemu-system-aarch64 -semihosting -m 128M -nographic -monitor none -serial stdio -machine virt,gic-version=2,secure=on,virtualization=on -cpu cortex-a53 -kernel hello.axf -S -gdb tcp::9000
The result of debug session is given below:
gdb) target remote localhost:9000
Remote debugging using localhost:9000
_start () at /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/libgloss/aarch64/crt0.S:90
90 /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/libgloss/aarch64/crt0.S: No such file or directory.
(gdb) si
<The system hangs here>
I have tried to disassemble the code using gdb and its output is given below. It looks like the code is not loaded correctly
(gdb) disas frame_dummy
Dump of assembler code for function frame_dummy:
0x0000000080001110 <+0>: udf #0
0x0000000080001114 <+4>: udf #0
0x0000000080001118 <+8>: udf #0
0x000000008000111c <+12>: udf #0
0x0000000080001120 <+16>: udf #0
0x0000000080001124 <+20>: udf #0
0x0000000080001128 <+24>: udf #0
0x000000008000112c <+28>: udf #0
0x0000000080001130 <+32>: udf #0
0x0000000080001134 <+36>: udf #0
0x0000000080001138 <+40>: udf #0
0x000000008000113c <+44>: udf #0
0x0000000080001140 <+48>: udf #0
0x0000000080001144 <+52>: udf #0
End of assembler dump.
Could you please shed some light on this. Any hint given is appreciated very much.
The Foundation Model and the QEMU 'virt' board are not the same machine type. They have different devices at different physical addresses, and in particular they do not have RAM at the same address. To run bare metal code on the 'virt' machine type you will need to adjust your code. This is normal for bare metal -- the whole point is that you are running directly on some piece of (emulated) hardware and need to match the details of it.
Specifically, the minimum change you need to make here is that the RAM on the 'virt' board starts at 0x4000_0000, not the 0x8000_0000 that the Foundation Model uses. There may be others as well, but that is the immediate cause of what you're seeing.

reference to external function in disassembly code [duplicate]

If I run objdump -d on a (linux amd64) .o file, function calls show up without the link time resolution done. Example:
90: 66 89 44 24 1c mov %ax,0x1c(%rsp)
95: 44 89 74 24 10 mov %r14d,0x10(%rsp)
9a: e8 00 00 00 00 callq 9f <foo+0x9f>
9f: 83 f8 ff cmp $0xffffffffffffffff,%eax
a2: 74 5e je 102 <foo+0x102>
A branch within the function shows up properly, but the callq is just the stub put in for the linker (with four bytes of zeros available for the linker to put a proper address into).
Is there a way, without actually linking, to get an assembly listing that has the function names resolved? I don't care about the address that will eventually be used, just the name of the function. That info has got to be in the .o file, since the linker must consume it to do its job.
I ask because the shared lib that the code in question goes into is about 140Mb, and it takes a long time to run objdump -d on that to get the asm dump with all the function calls resolved to their actual names.
Is there a way, without actually linking, to get an assembly listing that has the function names resolved?
Yes: use objdump -dr foo.o

How the assembly file is generated from the perl script in OpenSSL

In the opensource code of OpenSSL(version 1.1.0e) I saw that some of the function definition is generated by the perl files present inside the folders.
In the build.info file present in each folders inside the crypto, they have written some lines to generate the .s from the corresponding .pl.
For example, for generating aes_p8_set_encrypt_key in crypto/aes/build.info:
GENERATE[aesp8-ppc.s]=asm/aesp8-ppc.pl $(PERLASM_SCHEME)
for generating OPENSSL_madd300_probe in crypto/build.info :
GENERATE[ppccpuid.s]=ppccpuid.pl $(PERLASM_SCHEME)
And also in the main Makefile(generated makefile), there are some lines as below:
crypto/aes/aes-x86_64.o: crypto/aes/aes-x86_64.s
$(CC) -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes-x86_64.d.tmp -MT $# -c -o $# crypto/aes/aes-x86_64.s
#touch crypto/aes/aes-x86_64.d.tmp
#if cmp crypto/aes/aes-x86_64.d.tmp crypto/aes/aes-x86_64.d > /dev/null 2> /dev/null; then \
rm -f crypto/aes/aes-x86_64.d.tmp; \
else \
mv crypto/aes/aes-x86_64.d.tmp crypto/aes/aes-x86_64.d; \
fi
Followed with :
crypto/aes/aes-x86_64.s: crypto/aes/asm/aes-x86_64.pl
CC="$(CC)" $(PERL) crypto/aes/asm/aes-x86_64.pl $(PERLASM_SCHEME) $#
Can anyone explain how the .s is generated from the .pl files?
I need to add them in my Makefile inside my project, to solve the undefined reference error coming for the functions whose definition is generated by the .pl file.
How the assembly file is generated from the Perl script in OpenSSL...
You are using the Cryptogams implementation of AES on Power8. Cryptogams is Andy Polyakov's project to provide high speed cryptography to other developers.
The assembly language file is generated with a xlat program. For the Power8 gear the file is ppc-xlate.pl in the perlasm directory. It is used by aesp8-ppc.pl in the crypto/aes/asm directory.
Here is how you translate it. I'm working from GCC112 on the compile farm, which is ppc64le.
git clone https://github.com/openssl/openssl.git
mkdir cryptogams
cp ./openssl/crypto/perlasm/ppc-xlate.pl cryptogams/
cp ./openssl/crypto/aes/asm/aesp8-ppc.pl cryptogams/
cd cryptogams/
chmod +x *.pl
./aesp8-ppc.pl ppc64le aesp8-ppc.s
aesp8-ppc.pl generates a pure assembly language source file so name the output file with the little *.s. Sometimes the translation includes C preprocessor statements and it needs a big *.S (but not in this case).
The second argument to aesp8-ppc.pl is called flavor. It is ppc64le in the commands above. Flavor does two things. First, it selects either 32-bit or 64-bit. Second, it selects either little-endian or big-endian. Be sure to get the flavor right.
According to Andy at ppc8 does not build on powerpc64 big-endian, big-endian PowerPC should use linux64, not linux64be. Little-endian needs linux64le, however.
Once you have aesp8-ppc.s you can compile and assemble the source file with GCC.
gcc -mcpu=power8 -c aesp8-ppc.s
And then:
$ objdump --disassemble aesp8-ppc.o
aesp8-ppc.o: file format elf64-powerpcle
...
0000000000000420 <aes_p8_set_decrypt_key>:
420: c1 ff 21 f8 stdu r1,-64(r1)
424: a6 02 48 7d mflr r10
428: 50 00 41 f9 std r10,80(r1)
42c: 75 fc ff 4b bl a0 <aes_p8_set_encrypt_key>
430: a6 03 48 7d mtlr r10
434: 00 00 03 2c cmpwi r3,0
438: 68 00 c2 40 bne- 4a0 <Ldec_key_abort>
43c: 36 20 07 55 rlwinm r7,r8,4,0,27
440: 10 ff 65 38 addi r3,r5,-240
444: 7e f8 08 55 rlwinm r8,r8,31,1,31
448: 14 3a a3 7c add r5,r3,r7
44c: a6 03 09 7d mtctr r8
...
At this point you have an object file, but you don't know the API signatures or how to use it. To find out what to do next you have to objdump and then grep the OpenSSL sources to see how they use it.
$ nm aesp8-ppc.o | grep ' T '
00000000000006c0 T aes_p8_cbc_encrypt
0000000000001140 T aes_p8_ctr32_encrypt_blocks
00000000000005c0 T aes_p8_decrypt
00000000000004c0 T aes_p8_encrypt
0000000000000420 T aes_p8_set_decrypt_key
00000000000000a0 T aes_p8_set_encrypt_key
0000000000001d00 T aes_p8_xts_decrypt
0000000000001a60 T aes_p8_xts_encrypt
You are interested in the four functions aes_p8_set_encrypt_key, aes_p8_set_decrypt_key, aes_p8_encrypt and aes_p8_decrypt. You will use the signatures you find to create a header file for your program.
I'll help you with the first one: aes_p8_set_encrypt_key.
$ cd openssl
# Find aes_p8_set_encrypt_key
$ grep -nIR aes_p8_set_encrypt_key
crypto/evp/e_aes.c:153:# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
# Now look for HWAES_set_encrypt_key
$ grep -nIR HWAES_set_encrypt_key
...
crypto/evp/e_aes.c:2515:int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
...
# Now find the complete HWAES_set_encrypt_key
$ cat -n crypto/evp/e_aes.c
...
2515 int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
2516 AES_KEY *key);
Lather, rinse, repeat for AES_KEY, aes_p8_set_decrypt_key, aes_p8_encrypt and aes_p8_decrypt.
Eventually you will end up with a header like shown in Cryptogams | AES or Cryptogams | SHA on the OpenSSL wiki. Cryptogams | AES and Cryptogams | SHA are written for ARMv4 but the same applies to Power8 as well.
Andy dual licenses his work. One license is the OpenSSL license because Andy works for OpenSSL. The second license is a BSD style license that does not have the encumbrances of OpenSSL.
Andy's public source is at GitHub | dot-asm. Unfortunately, a lot of Andy's work has not been uploaded so you have to pull it from OpenSSL. And a lot it is not documented so you have to do a fair amount of poking and prodding in the OpenSSL sources.
As far as I know there are two places you can look for documentation on using Cryptogams and Power8 cryptography. First is the OpenSSL wiki pages Cryptogams | AES and Cryptogams | SHA. The tutorials are ARMv4 but it applies to Power 8, too. I wrote the wiki articles so errors and omissions are my mistakes.
The second place to look is GitHub and Noloader | POWER8 crypto. I help maintain Crypto++ and the POWER8 crypto book is my knowledge dump. The POWER8 book includes Cryptogams SHA for PowerPC in Chapter 7.
The POWER8 crypto book was written by Bill Schmidt and I because we could not find documentation when working with AES and SHA on Power8. Bill Schmidt works for IBM and even he could not get the docs. All we could find was a blog post from an IBM engineer that was grossly missing details.

How to write inline assembly in FreeDOS

I'm trying to write the following program to dump the interrupt vector table using FreeDOS in a virtual machine. I know that DEBUG will allow me to write an assembly program, but how do I create the following IVTDUMP.COM file, save it and run it?
Note: I'd like to try and do it all straight from FreeDOS if possible. I tried using the EDIT command but it errors out and I'm pretty sure I'm missing something.
for
(
address=IDT_255_ADDR;
address>=IDT_001_ADDR;
address=address-IDT_VECTOR_SZ,vector--
)
{
printf("%03d %08p ",vector,address);
__asm
{
PUSH ES
MOV AX,0
MOV ES,AX
MOV BX,address
MOV AX,ES:[BX]
MOV ipAddr,AX
INC BX
INC BX
MOV AX,ES:[BX]
MOV csAddr,AX
POP ES
};
printf("[CS:IP]=[%04X,%04X]\n",csAddr,ipAddr);
}
Things like for, address and printf are not part of assembly. You will have to rewrite that to actual assembly code or copy the macros and assembler you want to use to your freedos environment.
If you want to use debug as included in freedos you can use the a command to start writing assembly instructions, the n command to give a name and w to write the code to the file.
C:\debug
-a
06BC:0100 int 20
06BC:0102
-n ivtdump.com
-rcx 2
-w
Writing 0002 bytes.
-q
C:\
This sample program only exits the program through int 20. (The 2 after rcx indicates the length of the program to write to disk)

way to disassemble windows exe files in linux

Is there any way to disassemble windows exe files in linux?
Would this involve Wine? If so, is there any windows debug/disassembly program available for linux?
And can this be done with gdb?
Thnx.
objdump -d works for me (I have version 2.24):
$ objdump -d ~/.wine/drive_c/Program\ Files\ \(x86\)/Internet\ Explorer/iexplore.exe |head
/home/user/.wine/drive_c/Program Files (x86)/Internet Explorer/iexplore.exe: file format pei-i386
Note that I tried other binaries, including ntoskrnl.exe and Steam.exe and they also work with objdump
Disassembly of section .text:
10001000 <.text>:
10001000: b8 01 00 00 00 mov $0x1,%eax
10001005: c2 04 00 ret $0x4
For me, gdb didn't work, even when running with wine:
/home/user/.wine/drive_c/Program Files (x86)/Internet Explorer/iexplore.exe: not an ELF binary... don't know how to load it
Check out IDA Debugger Used it in the past with success.

Resources