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?!
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
oops This happens with all versions even v2.55, I downloaded the last version v2.56, and it works fine
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
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
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
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.
-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?
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
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.