Questions regarding PLT/GOT and statically linking - reverse-engineering

Hey so I was looking at the assembly code of a heap-overflow challenge (heap3 in protostar) in which use a vulnerability of an old version of dlmalloc to execute the exploit. Below is the assembler dump
0x08048889 <main+0>: push ebp
0x0804888a <main+1>: mov ebp,esp
0x0804888c <main+3>: and esp,0xfffffff0
0x0804888f <main+6>: sub esp,0x20
0x08048892 <main+9>: mov DWORD PTR [esp],0x20
0x08048899 <main+16>: call 0x8048ff2 <malloc>
0x0804889e <main+21>: mov DWORD PTR [esp+0x14],eax
0x080488a2 <main+25>: mov DWORD PTR [esp],0x20
0x080488a9 <main+32>: call 0x8048ff2 <malloc>
0x080488ae <main+37>: mov DWORD PTR [esp+0x18],eax
0x080488b2 <main+41>: mov DWORD PTR [esp],0x20
0x080488b9 <main+48>: call 0x8048ff2 <malloc>
0x080488be <main+53>: mov DWORD PTR [esp+0x1c],eax
0x080488c2 <main+57>: mov eax,DWORD PTR [ebp+0xc]
0x080488c5 <main+60>: add eax,0x4
0x080488c8 <main+63>: mov eax,DWORD PTR [eax]
0x080488ca <main+65>: mov DWORD PTR [esp+0x4],eax
0x080488ce <main+69>: mov eax,DWORD PTR [esp+0x14]
0x080488d2 <main+73>: mov DWORD PTR [esp],eax
0x080488d5 <main+76>: call 0x8048750 <strcpy#plt>
0x080488da <main+81>: mov eax,DWORD PTR [ebp+0xc]
0x080488dd <main+84>: add eax,0x8
0x080488e0 <main+87>: mov eax,DWORD PTR [eax]
0x080488e2 <main+89>: mov DWORD PTR [esp+0x4],eax
0x080488e6 <main+93>: mov eax,DWORD PTR [esp+0x18]
0x080488ea <main+97>: mov DWORD PTR [esp],eax
0x080488ed <main+100>: call 0x8048750 <strcpy#plt>
0x080488f2 <main+105>: mov eax,DWORD PTR [ebp+0xc]
0x080488f5 <main+108>: add eax,0xc
0x080488f8 <main+111>: mov eax,DWORD PTR [eax]
0x080488fa <main+113>: mov DWORD PTR [esp+0x4],eax
0x080488fe <main+117>: mov eax,DWORD PTR [esp+0x1c]
0x08048902 <main+121>: mov DWORD PTR [esp],eax
0x08048905 <main+124>: call 0x8048750 <strcpy#plt>
0x0804890a <main+129>: mov eax,DWORD PTR [esp+0x1c]
0x0804890e <main+133>: mov DWORD PTR [esp],eax
0x08048911 <main+136>: call 0x8049824 <free>
0x08048916 <main+141>: mov eax,DWORD PTR [esp+0x18]
0x0804891a <main+145>: mov DWORD PTR [esp],eax
0x0804891d <main+148>: call 0x8049824 <free>
0x08048922 <main+153>: mov eax,DWORD PTR [esp+0x14]
0x08048926 <main+157>: mov DWORD PTR [esp],eax
0x08048929 <main+160>: call 0x8049824 <free>
0x0804892e <main+165>: mov DWORD PTR [esp],0x804ac27
0x08048935 <main+172>: call 0x8048790 <puts#plt>
0x0804893a <main+177>: leave
0x0804893b <main+178>: ret
End of assembler dump.
Now looking at the assembler dump what I can understand is malloc and free are linked to the binary statically, while strcpy and puts are linked using PLT.
When I try to compile this program using it's source code, I get malloc#plt and free#plt, which when compiled on my local machine uses the wrong version of dlmalloc. The challenge is compiled and placed on a debian distro which we have to boot up in order to try this challenge but I would like to try it on my local machine. Can someone explain how I will be able to compile it so that malloc and free are statically linked with the binary.

Related

Exception when the program is removing characters from the specified text

Task: write a program to remove the central character in all words of odd length in a given text.
I did this (the idea of ​​the algorithm is to find and write the indexes by which the space is located (in the first cycle) and then rewrite the string with missing characters where necessary):
.586
.model flat, C
option casemap: none
include c:\masm32\include\msvcrt.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\msvcrt.lib
includelib c:\masm32\lib\kernel32.lib
printf PROTO C, :VARARG
.data
src db 'hello masm32_ wrld lb 7',0
len equ $-src
dest db ' ',len dup(0),0
end_index db len/2 dup(0)
msg2 db ' %d ', 0
count_1 db 0
count_2 db 0
.code
start:
symbol equ ' '
xor ecx,ecx
xor ebx,ebx
lea esi,src
dec ebx
next:
inc ebx
cmp byte ptr [esi],symbol
jnz notfound
inc ecx
mov byte ptr [end_index + ecx], bl
notfound:
inc esi
cmp byte ptr [esi],0
jz exit
jmp next
exit:
lea esi, src
lea edi, dest
mov ebx, 1
xor ecx, ecx
##_next:
.if byte ptr [end_index + ebx] == 0
jmp ##_ret
.endif
mov al, byte ptr [end_index + ebx]
mov ah, byte ptr [end_index + ebx - 1]
sub al, ah
xor ah, ah
push ebx
mov bl, 2
div bl
pop ebx
add al, byte ptr [end_index + ebx - 1]
and eax, 000000ffh
.if al == cl
inc count_1
inc count_2
inc ebx
jmp ##_next
.endif
mov al, byte ptr [esi + count_1]
mov byte ptr [edi + count_2], al
inc count_1
inc count_2
jmp ##_next
##_ret:
invoke printf, offset dest , 0
ret
end start
But at the first pass of the loop I get
An exception was thrown at address 0x00042092 in asm_7_deb.exe: 0xC0000005: Read access violation at address 0x0008A045.
dissassembler:
start:
00042020 xor ecx,ecx
00042022 xor ebx,ebx
00042024 lea esi,[src (045000h)]
0004202A dec ebx
next:
0004202B inc ebx
0004202C cmp byte ptr [esi],20h
0004202F jne _start+18h (042038h)
00042031 inc ecx
00042032 mov byte ptr end_index (045032h)[ecx],bl
notfound:
00042038 inc esi
00042039 cmp byte ptr [esi],0
0004203C je _start+20h (042040h)
0004203E jmp _start+0Bh (04202Bh)
exit:
00042040 lea esi,[src (045000h)]
00042046 lea edi,[dest (045018h)]
0004204C mov ebx,1
00042051 xor ecx,ecx
##_next:
00042053 cmp byte ptr end_index (045032h)[ebx],0
0004205A jne _start+3Eh (04205Eh)
0004205C jmp _start+8Ch (0420ACh)
#C0001:
0004205E mov al,byte ptr end_index (045032h)[ebx]
00042064 mov ah,byte ptr [ebx+45031h]
0004206A sub al,ah
0004206C xor ah,ah
0004206E push ebx
0004206F mov bl,2
00042071 div al,bl
00042073 pop ebx
00042074 add al,byte ptr [ebx+45031h]
0004207A and eax,0FFh
0004207F cmp al,cl
00042081 jne _start+72h (042092h)
00042083 inc byte ptr [count_1 (045045h)]
00042089 inc byte ptr [count_2 (045046h)]
0004208F inc ebx
00042090 jmp _start+33h (042053h)
#C0003:
00042092 mov al,byte ptr count_1 (045045h)[esi] ; <==== probably it happend here
00042098 mov byte ptr count_2 (045046h)[edi],al ; but i do not understand why
0004209E inc byte ptr [count_1 (045045h)]
000420A4 inc byte ptr [count_2 (045046h)]
000420AA jmp _start+33h (042053h)
##_ret:
000420AC push 0
000420AE push offset dest (045018h)
000420B3 call _printf (041005h)
000420B8 add esp,8
000420BB ret
In order to load [esi + count_1] you need to load the value of count_1 into a register first. Otherwise it takes the address of count_1 plus the value of esi, which is not what you want.
Since count_1 is a byte, use:
movzx edx, byte ptr [count_1]
mov al, [esi+edx]

InternetOpenA EXCEPTION_ACCESS_VIOLATION

I do call InternetOpenA in assembler
It is failing with EXCEPTION_ACCESS_VIOLATION on this command:
movdqa xmmword ptr [rsp + 0x20], xmm0
source
start:
sub rsp,30h
lea rcx, [userAgent]
mov rdx,INTERNET_OPEN_TYPE_DIRECT
mov r8,0
mov r9,0
mov qword ptr ds:[rsp+20],0
call qword ptr ds:[<&InternetOpenA>] <---------------
i edit 1st post
its entry point
i will add
sub rsp, 8
and its work
start:
sub rsp, 8
sub rsp,30h
lea rcx, [userAgent]
mov rdx,INTERNET_OPEN_TYPE_DIRECT
mov r8,0
mov r9,0
mov qword ptr ds:[rsp+20],0
call qword ptr ds:[<&InternetOpenA>] <---------------
but i dont understand why stack not aligned at start

Stuck figuring out what assembly function does

I know this question is a little general, but I've been going through a large assembly file and I'm up until this function is called:
CPU Disasm
Address Hex dump Command Comments
004149E0 /$ 55 PUSH EBP
004149E1 |. 89E5 MOV EBP,ESP
004149E3 |. 83EC 28 SUB ESP,28
004149E6 |. 895D F4 MOV DWORD PTR SS:[LOCAL.3],EBX
004149E9 |. 8B45 08 MOV EAX,DWORD PTR SS:[ARG.1]
004149EC |. 8975 F8 MOV DWORD PTR SS:[LOCAL.2],ESI
004149EF |. 897D FC MOV DWORD PTR SS:[LOCAL.1],EDI
004149F2 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
004149F4 |. 8945 E0 MOV DWORD PTR SS:[LOCAL.8],EAX
004149F7 |. 8B40 F4 MOV EAX,DWORD PTR DS:[EAX-0C]
004149FA |. 8945 E4 MOV DWORD PTR SS:[LOCAL.7],EAX
004149FD |. 8945 F0 MOV DWORD PTR SS:[LOCAL.4],EAX
00414A00 |. 8B45 0C MOV EAX,DWORD PTR SS:[ARG.2]
00414A03 |. 890424 MOV DWORD PTR SS:[LOCAL.10],EAX ;string => [ARG.2]
00414A06 |. E8 35C9FFFF CALL <JMP.&msvcrt.strlen> ;MSVCRT.strlen
00414A0B |. 8945 EC MOV DWORD PTR SS:[LOCAL.5],EAX
00414A0E |. 89C3 MOV EBX,EAX
00414A10 |. 8D45 EC LEA EAX,[LOCAL.5]
00414A13 |. 3B5D E4 CMP EBX,DWORD PTR SS:[LOCAL.7]
00414A16 |. 72 03 JB SHORT 00414A1B
00414A18 |. 8D45 F0 LEA EAX,[LOCAL.4]
00414A1B |> FC CLD
00414A1C |. 8B08 MOV ECX,DWORD PTR DS:[EAX]
00414A1E |. 8B75 E0 MOV ESI,DWORD PTR SS:[LOCAL.8]
00414A21 |. 8B7D 0C MOV EDI,DWORD PTR SS:[ARG.2]
00414A24 |. 39C9 CMP ECX,ECX
00414A26 |. F3:A6 REPE CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
00414A28 |. 0F92C0 SETB AL
00414A2B |. 0F97C2 SETA DL
00414A2E |. 28C2 SUB DL,AL
00414A30 |. 0FBEC2 MOVSX EAX,DL
00414A33 |. 85C0 TEST EAX,EAX
00414A35 |. 75 05 JNZ SHORT 00414A3C
00414A37 |. 8B45 E4 MOV EAX,DWORD PTR SS:[LOCAL.7]
00414A3A |. 29D8 SUB EAX,EBX
00414A3C |> 8B5D F4 MOV EBX,DWORD PTR SS:[LOCAL.3]
00414A3F |. 8B75 F8 MOV ESI,DWORD PTR SS:[LOCAL.2]
00414A42 |. 8B7D FC MOV EDI,DWORD PTR SS:[LOCAL.1]
00414A45 |. 89EC MOV ESP,EBP
00414A47 |. 5D POP EBP
00414A48 \. C3 RETN
This function is really giving me a hard time, if you guys have any insights at all or can give me a general idea of what's happening with it I'd really appreciate it.
I am guessing it might have something to do with the size of a string being checked (maybe for a length of 10 chars?) Also from what I've seen (again, not sure) AL and EAX are the ones in this code that I'm really worried about.
If more information is needed about any parts of this please don't hesitate to ask me.
Well, unoptimized x86 (not x86-64) assembly is pretty ugly (and in intel-syntax to boot... ugh)
Anyway, it seems this function takes the strlen() of a string, then takes the smaller of this strlen and a parameter passed in an array or struct, and uses it as the length-parameter for a strncmp(). The result of the strncmp is returned.

Modifying given variables in ASM

This is the ASM code:
__declspec(naked) void foo(something* t)
{
__asm {
push ebp
mov ebp, esp
mov eax, dword ptr [t]
mov dword ptr [eax], 0
mov dword ptr [eax+4], 0
mov esp, ebp
pop ebp
}
This would be the C version of the code:
struct something {
_int64 a;
_int64 b;
_int64 c;
};
void foo(struct* something) {
something->a = 0;
}
Now, I am wonder if I could do the same thing without storing t in eax. And just use ebp instead. But I am not sure where "a" would be (ebp+28 or ebp), and if it is even possible. This doesn't seem to work. Does anyone if this is possible, and how?
mov dword ptr [ebp+28], 0
mov dword ptr [ebp+24], 0
Arbitrary nesting of expressions is not possible in assembly. That's what high level languages were invented for. In other words, yes, you have to load the value of t into a register if you want to dereference it. Assembly does not support constructs like
mov dword ptr [[ebp+28]], 0
which is what you're aiming for. ebp+28 is not the address of t->a; it's the address of t, which is the address of t->a.
Also, the assembly snippet zeros out both t->a and t->b while the C one only does a. They're not equivalent.

After executing this nasm function main doesn't continue. It exits without errors

I call the function the following way from main:
main:
;memory alocation ect
call encode
The encode function looks like this:
It does a simple RLE algorithm.
encode:
;IN eax - pointer a memoria elejere
;IN ecx - sor hossza
;OUT eax -pointer az eredmeny elejere
;OUt ecx -a kiirt sor hossza
;elso char
Here it reads the first characer
;push eax
push ebp
xor ebp,ebp
push esi
push edi
push eax
xor edi,edi
Here it allocates memory:
;lefoglal memoria eredmenynek
mov ebx,eax
mov eax,ecx
call mem_alloc
;esi legyen eredmeny memoria kezdete
mov esi,eax
mov eax,ebx
;eax ismet a memoria poiter
xor edx,edx
mov dl,[eax]
; push eax
; xor eax,eax
; mov al,dl
; call io_writeint
; call mio_writeln
; pop eax
;lastChar az elso char
mov [lastChar],dl
The main loop the loops to the "vector"
inc ebp
;dec ecx
.goloop:
mov dl,[eax+ebp]
xor ebx,ebx
mov bl,[lastChar]
cmp dl,bl
jne .newChar
xor ebx,ebx
mov bl,[count]
inc bl
mov [count],bl
.backloop:
loop .goloop
.newChar:
mov [esi+edi],bl
inc edi
mov byte[esi+edi],-1
inc edi
mov bl,[count]
mov [esi+edi],bl
inc edi
mov byte[count],0
cmp ecx,0
ja .backloop
.veg:
mov ebx,esi
mov edx,edi
pop edi
pop esi
pop eax
pop ebp
pop eax
mov eax,ebx
mov ecx,edx
ret
It appears that you push four registers onto the stack but pop five off.
When you CALL an address, the instruction pointer is pushed onto the stack, then the processor JMPs to the label/address you specify. When RET is executed, it POPs off the stack and jumps to the address that it popped off. RET expects that the address that CALL pushed onto the stack will be the next word in the stack, but you have already popped this byte off when you popped more registers than you pushed.
You could try taking the very last
push eax
out of your code.