I am currently using Radare2 to extract opcodes from PE files. Currently, I am attempting to use the "pd" command which from the API: "pd n # offset: Print n opcodes disassembled". I am wondering if there is a way to calculate/find out exactly what "n" is for each file I process. Thanks
ENVIRONMENT
radare2: radare2 4.2.0-git 23519 # linux-x86-64 git.4.1.1-84-g0c46c3e1e commit: 0c46c3e1e30bb272a5a05fc367d874af32b41fe4 build: 2020-01-08__09:49:0
system: Ubuntu 18.04.3 LTS
SOLUTION
This example shows 4 different options to view / print disassembly or opcodes.
View disassembly in radare2 via visual mode:
Command one: aaaa # Analyze the file
Command two: Vp # Open disassembly in visual mode
Print disassembly of all functions in r2 or r2pipe:
Command one: aaaa # Analyze the file
Command two: pdf ##f > out
pdf # Print disassembly of a function
##f # Repeat the command for every function
> out # Redirect the output to the file named out
Print only the instruction in r2 or r2pipe:
Command one: aaaa # Analyze the file
Command two: pif ##f ~[0] > out
pif # Print instructions of a function
##f # Repeat the command for every function
~[0] # Only print the first column (The instruction)
> out # Redirect the output to the file named out
Obtained detailed information for each opcode using r2 or r2pipe:
Command one: aaaa # Analyzey the file
Command two: aoj ##=`pid ##f ~[0]` > out
aoj # Display opcode analysis information in JSON
##= # Repeat the command for every offset return by sub-query
pid ##f ~[0] # The sub-query
pid # Print disassembly with offset and bytes
##f # Repeat the command for every function
~[0] # Only print the first column (The offset)
> out # Redirect the output to the file named out
EXAMPLE
Replace the commands here with any option from above.
Example using radare2 shell
user#host:~$ r2 /bin/ls
[0x00005850]> aaaa
...
[0x00005850]> pdf ##f > out
[0x00005850]> q
user#host:~$ cat out
...
┌ 38: fcn.00014840 ();
│ ; var int64_t var_38h # rsp+0xffffffd0
│ 0x00014840 53 push rbx
│ 0x00014841 31f6 xor esi, esi
│ 0x00014843 31ff xor edi, edi
│ 0x00014845 e846f2feff call sym.imp.getcwd
│ 0x0001484a 4885c0 test rax, rax
│ 0x0001484d 4889c3 mov rbx, rax
│ ┌─< 0x00014850 740e je 0x14860
│ │ ; CODE XREF from fcn.00014840 # 0x14868
│ ┌──> 0x00014852 4889d8 mov rax, rbx
│ ╎│ 0x00014855 5b pop rbx
│ ╎│ 0x00014856 c3 ret
..
│ ╎│ ; CODE XREF from fcn.00014840 # 0x14850
│ ╎└─> 0x00014860 e88beffeff call sym.imp.__errno_location
│ ╎ 0x00014865 83380c cmp dword [rax], 0xc
│ └──< 0x00014868 75e8 jne 0x14852
└ 0x0001486a e861feffff call fcn.000146d0
; CALL XREFS from fcn.00013d00 # 0x13d9d, 0x13da8
...
Example using Python with r2pipe
import r2pipe
R2 = r2pipe.open('/bin/ls') # Open r2 with file
R2.cmd('aaaa') # Analyze file
R2.cmd('pdf ##f > out') # Write disassembly for each function to out file
R2.quit() # Quit r2
Related
I'm trying to put a small boot loader into the mbr of an exfat drive, but I'm having trouble getting ld to set the virtual address correctly.
according to the ExFat Specification, I need to put the bootloader at byte 0x78 (120). So I set the location counter to 0x7C78. But when I used readelf on the result, I found that ld put the virtual address at 0x7C80 instead.
This is sadly not what I want, so I tried to set the virtual address to different values and found that ld will always put the section with a 16 byte alignment. e.g. at 0x7C70 and 0x7C80
My question is: Is there any way to disable/override this alignment, and put my section at the specific address
The boot code
bits 16
global boot
boot:
mov ax, 0x0202
mov bx, 0x7E00
mov cx, 0x0002
mov dx, 0x0080
int 0x13
jmp 0x0000:0x7e00
times 388-($-$$) db 0x00
dw 0xAA55
The linkerscript
OUTPUT_FORMAT("binary")
SECTIONS {
. = 0x7c78;
.text :
{
*.mbr.o(.text)
}
.text :
{
*.o(.text)
}
}
The readelf result
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/boot/boot.mbr.s
2: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .debug_info
3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .debug_abbrev
4: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .debug_line
5: 0000000000007c93 1 OBJECT LOCAL DEFAULT 1 boot.end
6: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/boot/boot.s
7: 0000000000007e10 0 SECTION LOCAL DEFAULT 2 .text
wrong > 0000000000007c80 0 NOTYPE GLOBAL DEFAULT 1 boot
9: 0000000000007e10 0 NOTYPE GLOBAL DEFAULT 2 stage2
I used these flags to call nasm:
nasm -felf64 -g -F dwarf -o boot.mbr.o boot.mbr.s
and these flags to call ld
i386-elf-gcc -nostdlib -n -Wl,--oformat=elf64-little -T linker.ld -o boot.elf boot.mbr.o
The Microsoft Windows Dev Center Dashboard lets me collect stack traces from failures in my native desktop app in the wild.
Unfortunately, minidumps aren't avaialble. I just get a TSV file that (sometimes) has a stack trace in it, which looks like this:
Frame Image Function Offset
0 MyApp 0x2F59A1
1 MyApp 0x11CEA8
2 MyApp 0x11AE74
3 MyApp 0x151289
4 MyApp 0x2A686
5 MyApp 0x180720
6 MyApp 0x1807B6
7 MyApp 0x2E875A
8 MyApp 0x2E8882
9 kernel32 BaseThreadInitThunk 0x24
10 ntdll __RtlUserThreadStart 0x2B
11 ntdll _RtlUserThreadStart 0x1B
To make this uesful, I load the matching binary in WinDbg, figure out the offset plus the base address, and unassemble at the resulting address. If my app loads at 0x00400000, I add 0x2F59A1 to it and get 0x006F59A1. Unassembling there shows me the return address of that stack frame, so I can get some idea of what the crash is about.
Is there a better way? How can I request minidumps from Dev Center? (Microsoft Support says I just can't. Really?) Is there a script to convert at TSV file a usable stack trace so I don't manually evaluate each stack frame? Is there some other way?
I don't know if you can get a .dmp or not google says you can not get one from dash board
the answer below is a modified version of a script
I once used it to disassemble # .map file offsets improvise if needed
it takes the offsets from the column using pandas
creates a command string and uses subprocess to disassemble at that offset
i assume the tsv is a tab seperated value file if not you have some tweaking to do
assuming tab seperated file with data like below
Frame Image Function Offset
0 calc 0x1012
0 calc 0x1015
you can automate the process with some for loops in the code below
edit since i do two subprocess calls the offsets for both forward and backward disassembly are different (ASLR effect )
:\>cat Untitled.py
import pandas as pd
df = pd.read_csv("tsv.txt" , delimiter='\t')
print df
offset = df.Function.unique()[1]
print offset
import subprocess
cmdline = "cdb -c \"ub calc+"+offset+";q\" calc.exe | tail"
print cmdline
output = subprocess.check_output(cmdline ,shell=True )
print output
cmdline = "cdb -c \"u calc+"+offset+";q\" calc.exe | tail"
print cmdline
output = subprocess.check_output(cmdline ,shell=True )
print output
:\>python Untitled.py
Frame Image Function Offset
0 0 calc 0x1012 NaN
1 0 calc 0x1015 NaN
0x1015
cdb -c "ub calc+0x1015;q" calc.exe | tail
calc!_imp__SHGetFolderPathW+0x1:
00f31005 57 push edi
00f31006 1f pop ds
00f31007 7629 jbe calc!_imp__GdipCloneImage+0x2 (00f31032)
00f31009 a1237683dd mov eax,dword ptr ds:[DD837623h]
00f3100e 27 daa
00f3100f 7646 jbe calc!_imp__GdipDeleteGraphics+0x3 (00f31057)
00f31011 1e push ds
00f31012 197600 sbb dword ptr [esi],esi
quit:
cdb -c "u calc+0x1015;q" calc.exe | tail
calc!⌂SHELL32_NULL_THUNK_DATA+0x1:
009b1015 0000 add byte ptr [eax],al
009b1017 007a41 add byte ptr [edx+41h],bh
009b101a 5f pop edi
009b101b 7700 ja calc!⌂SHLWAPI_NULL_THUNK_DATA+0x1 (009b101d)
009b101d 0000 add byte ptr [eax],al
009b101f 005fa1 add byte ptr [edi-5Fh],bl
009b1022 687449a568 push 68A54974h
009b1027 744a je calc!_imp__GdiplusShutdown+0x3 (009b1073)
quit:
:\>
sorry if this question sounds dumb but I am very new to shellcoding and I was trying to get a hello world example to work on a 32 bit linux machine.
As this is shellcoding, I used a few tricks to remove null bytes and shorten the code. Here it is:
section .data
section .text
global _start
_start:
;Instead of xor eax,eax
;mov al,0x4
push byte 0x4
pop eax
;xor ebx,ebx
push byte 0x1
pop ebx
;xor ecx,ecx
cdq ; instead of xor edx,edx
;mov al, 0x4
;mov bl, 0x1
mov dl, 0x8
push 0x65726568
push 0x74206948
;mov ecx, esp
push esp
pop ecx
int 0x80
mov al, 0x1
xor ebx,ebx
int 0x80
This code works fine when I compile and link it with the following commands:
$ nasm -f elf print4.asm
$ ld -o print4 -m elf_i386 print4.o
However, I tried running it within the following C code:
$ cat shellcodetest.c
#include
#include
char *shellcode = "\x04\x6a\x58\x66\x01\x6a\x5b\x66\x99\x66\x08\xb2\x68\x68\x68\x65\x69\x48\x54\x66\x59\x66\x80\xcd\x01\xb0\x31\x66\xcd\xdb\x80";
int main(void) {
( *( void(*)() ) shellcode)();
}
$ gcc shellcodetest.c –m32 –z execstack -o shellcodetest
$ ./shellcodetest
Segmentation fault (core dumped)
Could someone please explain what is happening there? I tried running the code in gdb and noticed something weird happening with esp. But as I said before, I still lack experience to really understand what is going on here.
Thanks in advance!
Your shellcode does not work, because it is not entered in the correct endianness. You did not state how you extracted the bytes from the file print4, but both objdump and xxd gives the bytes in correct order.
$ xxd print4 | grep -A1 here
0000060: 6a04 586a 015b 99b2 0868 6865 7265 6848 j.Xj.[...hherehH
0000070: 6920 7454 59cd 80b0 0131 dbcd 8000 2e73 i tTY....1.....s
$ objdump -d print4
print4: file format elf32-i386
Disassembly of section .text:
08048060 <_start>:
8048060: 6a 04 push $0x4
8048062: 58 pop %eax
8048063: 6a 01 push $0x1
...
The changes you need to do is to swap the byte order, '\x04\x6a' -> '\x6a\x04'.
When I run your code with this change, it works!
$ cat shellcodetest.c
char *shellcode = "\x6a\x04\x58\x6a\x01\x5b\x99\xb2\x08\x68\x68\x65\x72\x65\x68\x48\x69\x20\x74\x54\x59\xcd\x80\xb0\x01\x31\xdb\xcd\x80";
int main(void) {
( *( void(*)() ) shellcode)();
}
$ gcc shellcodetest.c -m32 -z execstack -o shellcodetest
$ ./shellcodetest
Hi there$
I'm having problems with analyzing a simple binary in IDA Pro.
When running a program, i dumped part of its memory (for example, unpacked code section in the memory) into a file, using WinDbg.
I would like to analyze it using IDA, but when trying to just load the binary - it will only show its raw data.
Of course the binary is not a full PE file, so I'm not expecting a deep analysis, just a nicer way to read the disassembly.
So the question is - How can i make IDA disassemble the binary?
Thanks! :)
select an appropriate address and press c
that is MakeCode(Ea); ida will convert the raw bytes to code and disassemble it
pasted below is a simple automation with an idc script but idas automation is imho subpar so you should stick with manual pressing of C in user interface
:dir /b
foo.dmp
foo.idc
:xxd foo.dmp
0000000: 6a10 6830 b780 7ce8 d86d ffff 8365 fc00 j.h0..|..m...e..
0000010: 64a1 1800 0000 8945 e081 7810 001e 0000 d......E..x.....
0000020: 750f 803d 0850 887c 0075 06ff 15f8 1280 u..=.P.|.u......
0000030: 7cff 750c ff55 0850 e8c9 0900 00 |.u..U.P.....
:type foo.idc
#include <idc.idc>
static main (void) {
auto len,temp,fhand;
len = -1; temp = 0;
while (temp < 0x3d && len != 0 ) {
len = MakeCode(temp);
temp = temp+len;
}
fhand = fopen("foo.asm","wb");
GenerateFile(OFILE_LST,fhand,0,0x3d,0x1F);
fclose(fhand);
Wait();
Exit(0);
}
:f:\IDA_FRE_5\idag.exe -c -B -S.\foo.idc foo.dmp
:head -n 30 foo.asm | tail
seg000:00000000 ; Segment type: Pure code
seg000:00000000 seg000 segment byte public 'CODE' use32
seg000:00000000 assume cs:seg000
seg000:00000000 assume es:nothing, ss:nothing, ds:nothing, fs:no thing, gs:nothing
seg000:00000000 push 10h
seg000:00000002 push 7C80B730h
seg000:00000007 call near ptr 0FFFF6DE4h
seg000:0000000C and dword ptr [ebp-4], 0
with windbg you can get the disassembly right from command line like this
:cdb -c ".dvalloc /b 60000000 2000;.readmem foo.dmp 60001000 l?0n61;u 60001000 60001040;q" calc
0:000> cdb: Reading initial command '.dvalloc /b 60000000 2000;.readmem foo.dmp 60001000 l?0n61;u 60001000 60001040;q'
Allocated 2000 bytes starting at 60000000
Reading 3d bytes.
60001000 6a10 push 10h
60001002 6830b7807c push offset kernel32!`string'+0x88 (7c80b730)
60001007 e8d86dffff call 5fff7de4
6000100c 8365fc00 and dword ptr [ebp-4],0
60001010 64a118000000 mov eax,dword ptr fs:[00000018h]
60001016 8945e0 mov dword ptr [ebp-20h],eax
60001019 817810001e0000 cmp dword ptr [eax+10h],1E00h
60001020 750f jne 60001031
60001022 803d0850887c00 cmp byte ptr [kernel32!BaseRunningInServerProcess (7c885008)],0
60001029 7506 jne 60001031
6000102b ff15f812807c call dword ptr [kernel32!_imp__CsrNewThread (7c8012f8)]
60001031 ff750c push dword ptr [ebp+0Ch]
60001034 ff5508 call dword ptr [ebp+8]
60001037 50 push eax
60001038 e8c9090000 call 60001a06
6000103d 0000 add byte ptr [eax],al
6000103f 0000 add byte ptr [eax],al
quit:
ollydbg 1.10 view-> file-> (mask any file) -> foo.dmp -> rightclick -> disassemble
*How can I obtain a mem pointer with progress using GET-POINTER-VALUE....?
In Windows works fine:
DEFINE VARIABLE vUNO AS MEMPTR.
DEFINE VARIABLE vDOS AS MEMPTR.
DEFINE VARIABLE vTRES AS MEMPTR.
DEFINE VARIABLE sUNO AS CHARACTER.
DEFINE VARIABLE sDOS AS CHARACTER.
DEFINE VARIABLE sTRES AS CHARACTER.
DEFINE VARIABLE rUno AS MEMPTR.
/*Para prueba, poner algo a UNO, DOS y TRES.*/
DEFINE VARIABLE PTR AS MEMPTR.
ASSIGN sUNO = "Uno"
sDOS = "Dos"
sTRES = "Tres"
SET-SIZE(vUNO ) = LENGTH(sUNO ) * 2
SET-SIZE(vDOS ) = LENGTH(sDOS ) * 2
SET-SIZE(vTRES ) = LENGTH(sTRES) * 2
PUT-STRING(vUNO , 1) = sUNO
PUT-STRING(vDOS , 1) = sDOS
PUT-STRING(vTRES, 1) = sTRES.
SET-SIZE(PTR) = 4 /*Apuntador a vUNO -> 1*/
+ 4 /*Apuntador a vDOS -> 5*/
+ 4. /*Apuntador a vTRES -> 9*/
/*
NOTA:
4 porque en arquitcturas a 32 bits apuntadores miden 4 bytes.
Checar en Unix porque Hp-Ux (de Axa) es a 64 bits (apuntadores a 8 bytes).
*/
/* [1] 2 3 4 [5] 6 7 8 [9] 10 11 12 */
MESSAGE PROGRAM-NAME(1) SKIP
GET-STRING(vUNO,1 ) "/" GET-POINTER-VALUE(vUNO) SKIP
GET-STRING(vDOS,1 ) "/" GET-POINTER-VALUE(vDOS) SKIP
GET-STRING(vTRES,1) "/" GET-POINTER-VALUE(vTRES) SKIP
VIEW-AS ALERT-BOX INFO BUTTONS OK.
/******************************************/
It returns:
---------------------------
Información
---------------------------
C:\GMM2000\Temp\p19350.cmp
Uno / 87066920
Dos / 85914720
Tres / 85914744
---------------------------
Aceptar
---------------------------
but with the same code Unix returns:
---------------------------
Información
---------------------------
/gmm2000/p13659.cmp
Uno / ?
Dos / ?
Tres / ?
---------------------------
Aceptar
---------------------------
Please HEEEEEELLLLPPPPP!!!!*
The HP-UX 64bit AVM doesn't do 64bit pointers for some of the releases, as the external interfaces only do 32bits.I forget which version implemented full 64 bit pointers though - that would be a question to ask PSC TS.
I just tried your code on 10.2B Linux. It seems to work:
┌────────── Information ──────────┐
│ /home/tom/p04012_Untitled1.ped │
│ Uno / 16817200 │
│ Dos / 16992512 │
│ Tres / 16992544 │
│ ─────────────────────────────── │
│ <OK> │
└─────────────────────────────────┘
Know that we know that you are running 64 bit Progress v9 on HPUX...
In a 64 bit environment GET-POINTER-VALUE() returns a 64 bit result. But Progress v9 does not have an int64 data type. Try assigning the result to a DECIMAL variable. That should be able to hold the value.