Assembly Language, objdump? - disassembly

I'm trying to follow along in the Art of Exploitation book, yet when I got to the disassembly language portion I got a little lost, because my output after running the objdump -D a.out | grep -A20 main.: command that he wrote was different.
08048374 <main>:
8048374: 55____ push %ebp
8048375: 89 e5 __mov %esp,%ebp
8048377: 83 ec 08 sub $0x8,%esp
Mine looked like:
0000000000400530 <main>:
400530: 55 _____push %rbp
400531: 48 89 e5 mov %rsp, %rbp
Frankly I have no clue as to what is going on, anyone have better resources I could look to on the internet? Or a source that would explain to me little things like what the -d after objdump does? Google searches for arguments like -d or -l yields few results.

Related

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 to get Radare2 to use symbol table information for library calls?

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

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