News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

struct

Started by mabdelouahab, February 28, 2023, 06:18:29 PM

Previous topic - Next topic

mabdelouahab

OPTION LITERALS:ON
printf PROTO :VARARG
.data
struct1 struct
s1 dq 0
s2 dq 0
s3 dq 0
struct1 ends
W struct1 <>
.code
main  PROC  argc:QWORD, argv:QWORD
mov W.s1,1
mov W.s2,12
mov W.s3,133
invoke printf,"W.s1=%d\n",W.s1
invoke printf,"W.s2=%d\n",W.s2
invoke printf,"W.s3=%d\n",W.s3
xor rax,rax
ret
main  ENDP
end 


uasm -elf64   main.asm
gcc -o main main.o
./main

Output:

W.s1=133
W.s2=133
W.s3=133

WHY?!

mabdelouahab

Another test:
lea rax,W
mov qword ptr [rax],1
mov qword ptr [rax+8],12
mov qword ptr [rax+16],133
invoke printf,"W.s1=%d\n",W.s1
invoke printf,"W.s2=%d\n",W.s2
invoke printf,"W.s3=%d\n",W.s3

Output:
   W.s1=1
   W.s2=1
   W.s3=1

Another test
mov W.s1,1
mov W.s2,12
mov W.s3,133
lea rax,W
invoke printf,"W.s1=%d\n W.s2=%d\n W.s3=%d\n",qword ptr [rax],qword ptr [rax+8],qword ptr [rax+16]


Output:
   W.s1=133
   W.s2=0
   W.s3=0

mabdelouahab

oops This happens with all versions even v2.55, I downloaded the last version v2.56, and it works fine

mineiro

I was not able to reproduce this with that command line using uasm2.55.
If I change to:
gcc main.o -no-pie -o main
it works.
W.s1=1
W.s2=12
W.s3=133

When I download executable version 2.56 it gives to me:
$ ./uasm256 -elf64 main.uasm
./uasm256: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./uasm256)
./uasm256: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./uasm256)

$ ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9.9) 2.31

$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

So, I have compiled version2.56 to try.
But in version 2.56 I have an error in output (value 12):
W.s1=1
W.s3=133

I have tried other command line, and error is the same. I have inserted "invoke exit,1" in source code to not insert crt1.o,crtn.o and crti.o.
ld -o main -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc main.o
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

mabdelouahab

Hi mineiro
Quoteuasm -elf64   main.asm
gcc -o main main.o
UASM v2.55, Mar 30 2022, Masm-compatible assembler
ldd --version
ldd (GNU libc) 2.36
gcc --version
gcc (GCC) 12.2.1 20221121

OPTION LITERALS:ON
printf PROTO :VARARG
.data
struct1 struct
s1 dq 0
s2 dq 0
s3 dq 0
struct1 ends
W struct1 <>
.code
main  PROC  argc:QWORD, argv:QWORD
mov W.s1,1
mov W.s2,12
mov W.s3,133
invoke printf,"W.s1=%d\n",W.s1
invoke printf,"W.s2=%d\n",W.s2
invoke printf,"W.s3=%d\n",W.s3
xor rax,rax
ret
main  ENDP
end 

W.s1=133
W.s2=133
W.s3=133

mineiro

hello sir mabdelouahab;

I changed printf to puts, just to check, and the error here continues in uasm2.56:
W.s1=%d

W.s3=%d

I checked listing and are the same thing, .text and .data section are the same in both versions. Relocation is the problem here.
$ cmp -l main255.o main256.o | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'

00000449 F8 00
0000044A FF 00
0000044B FF 00
0000044C FF 00
0000044D FF 00
0000044E FF 00
0000044F FF 00
00000450 FF 00
...

Sounds that unsigned was changed by signed (or vice-versa) inside some internal uasm variable.

$ objdump -r main255.o

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_PC32     W-0x0000000000000008
0000000000000012 R_X86_64_PC32     W-0x0000000000000008
000000000000001d R_X86_64_PC32     W-0x0000000000000008
0000000000000028 R_X86_64_PC32     __ls3852-0x0000000000000004
000000000000002f R_X86_64_PC32     W-0x0000000000000004
0000000000000036 R_X86_64_PC32     puts-0x0000000000000004
000000000000003d R_X86_64_PC32     __ls32846-0x0000000000000004
0000000000000044 R_X86_64_PC32     W-0x0000000000000004
000000000000004b R_X86_64_PC32     puts-0x0000000000000004
0000000000000052 R_X86_64_PC32     __ls6751-0x0000000000000004
0000000000000059 R_X86_64_PC32     W-0x0000000000000004
0000000000000060 R_X86_64_PC32     puts-0x0000000000000004

$ objdump -r main256.o
RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_PC32     W-0x0000000000000008
0000000000000012 R_X86_64_PC32     W
000000000000001d R_X86_64_PC32     W+0x0000000000000008
0000000000000028 R_X86_64_PC32     __ls3852-0x0000000000000004
000000000000002f R_X86_64_PC32     W-0x0000000000000004
0000000000000036 R_X86_64_PC32     puts-0x0000000000000004
000000000000003d R_X86_64_PC32     __ls32846-0x0000000000000004
0000000000000044 R_X86_64_PC32     W+0x0000000000000004
000000000000004b R_X86_64_PC32     puts-0x0000000000000004
0000000000000052 R_X86_64_PC32     __ls6751-0x0000000000000004
0000000000000059 R_X86_64_PC32     W+0x000000000000000c
0000000000000060 R_X86_64_PC32     puts-0x0000000000000004
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

mineiro

So, I installed in a virtual machine an Ubuntu distro, libc version 2.35 and gcc 11.3.0.
Now, things switched, I have inserted switch -no-pie to compile.

Compiled version 2.56 downloaded from github shows:
W.s1=1
W.s2=12
W.s3=133

And version 2.55 compiled in this machine shows:
W.s1=133
W.s2=133
W.s3=133

Strange thing is that "objdump -r main*" show same results as posted before.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

johnsa

-no-pie is pretty much essential these days, linux needs the GOT and PLT for everything.. and these constructs are near on impossible to auto-manage in asm code, they have to be manually opted into and code
around. If you use -no-pie everything should work?

mabdelouahab

Quote from: johnsa on March 03, 2023, 07:52:25 PM
-no-pie is pretty much essential these days, linux needs the GOT and PLT for everything.. and these constructs are near on impossible to auto-manage in asm code, they have to be manually opted into and code
around. If you use -no-pie everything should work?
Hi johnsa
-no-pie is an options for linking and nothing changes when  I add it
this is after I disassemble it (Cutter Reverse)
mov W.s1,1
mov W.s2,12
mov W.s3,133

v2.55

0x00401134      mov     qword W, 1 ; 0x404030            <---- mov W.s1,1  ;this is ok
0x0040113f       mov     qword W, 0xc ; 0x404030       <----   mov W.s2,12 ;this is not Ok, it s equ (mov W.s1,12)
0x0040114a      mov     qword W, 0x85 ; 0x404030       <---- mov W.s3,133 ;and this is also, it s equ (mov W.s1,133)


v2.56

0x00401134      mov     qword W, 1 ; 0x404030                             <---- mov W.s1,1  ;this is ok
0x0040113f      mov     qword data.00404038, 0xc ; 0x404038         <---- mov W.s2,12  ;this is ok
0x0040114a      mov     qword data.00404040, 0x85 ; 0x404040         <---- mov W.s3,133  ;this is ok


mineiro

I think it's a relocation problem (maybe rip addressing can be wrong relative to data structure). In version 255 that shows 0,+8,+16, but in version 256 that show 0,16,32, ... .
You can check these assumptions by running commands bellow.
When printf shows 3 times 133 was because was pointing 3 times to w3. And mov 1,2,133 in reality was moving 1,2,133 to same location without displacement.
You can see showing 3 times number 1 if you initialize W structure in data section and comment that mov w1, 1 ... mov w2,2 and mov w2,133 from first example source code.


;uasm255 -elf64 main.uasm
;mv main.o main255.o
;uasm256 -elf64 main.uasm
;mv main.o main256.o

.X64
printf PROTO :VARARG
struct1 struct 16
s1 dq ?
s2 dq ?
s3 dq ?
struct1 ends

.data
W struct1 <1,12,133>
;dq 0                   ;<---| uncoment these 2 in any wrong version results and the error will "disappear"
;dq 2
ws1 db "W.s1=%d",10,0
ws2 db "W.s2=%d",10,0
ws3 db "W.s3=%d",10,0

.code
main  PROC argc:dWORD, argv:qWORD
invoke printf,addr ws1,W.struct1.s1
invoke printf,addr ws2,W.struct1.s2
invoke printf,addr ws3,W.struct1.s3
xor eax,eax
ret
main  ENDP
end 

Results in libc v2.31 is ok to uasm255 but in uasm256 result is:
W.s1=1
W.s2=133
W.s3=1932416768
if you uncoment that 2 qword bellow W struct definition in source code so result is:
W.s1=1
W.s2=133
W.s3=2

A binary diff show:
$ radiff2 main255.o main256.o
0x00000460 fcffffffffffffff => 0400000000000000 0x00000460
0x000004a8 fcffffffffffffff => 0c00000000000000 0x000004a8
Well, raddif2 probably its not present in your machine (radare2), but you can see this by using other command that are present like:

------------------------------------------------------------
checking relocations with objdump and readelf.
$ objdump -r main255.o > rel255.txt
$ objdump -r main256.o > rel256.txt
$ diff rel255.txt rel256.txt
------------------------------------------------------------
$ readelf -r main255.o > rel255.txt
$ readelf -r main256.o > rel256.txt
$ diff rel255.txt rel256.txt
------------------------------------------------------------
showing a disassembly with relocations:
$ objdump -Dr -M intel main255.o > rel255.txt
$ objdump -Dr -M intel main256.o > rel256.txt
$ diff rel255.txt rel256.txt
------------------------------------------------------------
;dump bytes at '.rela.text' section
$ readelf -S -R 6 main255.o > rel255.txt
$ readelf -S -R 6 main256.o > rel256.txt
$ diff rel255.txt rel256.txt
------------------------------------------------------------
So, if I overwrite bytes using a hex editor at main256.o (end of file):
at offset 460h      04000000 00000000  to   fcffffff ffffffff
at offset 4a8h      0c000000 00000000  to   fcffffff ffffffff

Compile and program execution works.
So, I think it's a relocation problem.
I do a little search in libc changelog and not find anything that can cause this error.


--edited---
I'm supposing that this happened from version 256 instead of 255 because if you try to use org directive (even being wrong in this case):
...
.code
org 401000h
...

So,
$ ./uasm256 -elf64 main.uasm
main.uasm : Error A2169: General Failure

But it's necessary check in libc version 2.32 to up if opposite thing happen.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything