void * cli_set_variable(char *var, char *val)
{
return 0x00ff00ff00ff00ff;
}
…
void *ret = cli_set_variable(var, val);
vp_log(ret);
Fordítás és futtatás után az alábbi log bejegyzést dobja a gép:
20140206 113043a [97002] [0000000111965000] [var:task.c:276:master_start_task()] ret: 0xff00ff
Némi debuggolás után:
0x000000010c17cf3b <master_start_task+1989>: mov $0x0,%eax
0x000000010c17cf40 <master_start_task+1994>: callq 0x10c177e13 <cli_set_variable>
0x000000010c17cf45 <master_start_task+1999>: cltq
0x000000010c17cf47 <master_start_task+2001>: mov %rax,-0x48(%rbp)
CLTQ:
cltq sign extends %eax to %rax
És így lesz egy pointer előjel bővítve… KÖSZI SRÁCOK. Vajon hány ilyen gcc által generált BoF leledzhet szerte a világon mindenféle szolgáltatásba és egyéb szoftverbe kódoltan?
- Pontscho blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
Mi ez a BoF? (ahhoz rövidnek tűnik, hogy a google válaszoljon)
- A hozzászóláshoz be kell jelentkezni
Buffer overflow.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Köszi. Más kérdés, hogy pointert ritkán szokás hexa konstansként visszaadni ;)
(ez valami egyéb probléma modellje volt vagy eleve konstanssal próbáltad?)
- A hozzászóláshoz be kell jelentkezni
Köszi. Más kérdés, hogy pointert ritkán szokás hexa konstansként visszaadni ;)
Valoban, de nem pelda nelkul allo esemeny. Legutobb iOS4 kamera kernel modul revengnel volt szuksegem OS fuggoen egy belepesi pont ilyesfele hasznalatara, mert egy adott allokacios fuggenyt maskepp nem lehetett elerni. De ez most csak test pattern.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
OK, ez most teszt: nem lehet, hogy a gcc a konstans miatt fordított hülyeséget? (találgatok, ezért kérdeztem, hogy volt-e valami konkrét előzménye)
Sajnos a mostani processzorok assembly-je távol áll tőlem (meg már azok is, amiket anno kívül-belül ismertem :( ), szóval ebből az egészből csak a C kódot fogtam fel, meg azt próbáltam, amit írtál. Az assembly részt akár kínai írásjelekkel is felvéshetted volna. ;)
- A hozzászóláshoz be kell jelentkezni
Azért ezt a pár utasítást nem olyan nehéz felfogni, még nekem is ment. ;) (Igaz én azért pislogtam, mert a gcc assembly dialektusában az utolsó paraméter a cél és nem az első, én meg azt szoktam meg.) A mov az csak megy, a callq is, a cltq-t leírta Pontscho, más meg nincs. A %rax az a 64 bites A regiszter, az %eax ennek az alsó 32 bitje, az %rbp a stack bázis pointer. Kihagytam valamit?
- A hozzászóláshoz be kell jelentkezni
Azert a cast-ot illene odairni, mas kerdes, hogy a fordito is warningol ettol a konverziotol. Erdemes lenne a szabvanyban megnezni, hogy mit mond erre, de nem feltetlen a gcc-t okolnam ebben az esetben, hogy hulyeseg lett az eredmeny.
- A hozzászóláshoz be kell jelentkezni
Dump of assembler code for function cli_set_variable:
0x0000000100008ec3 <cli_set_variable+0>: push %rbp
0x0000000100008ec4 <cli_set_variable+1>: mov %rsp,%rbp
0x0000000100008ec7 <cli_set_variable+4>: mov %rdi,-0x8(%rbp)
0x0000000100008ecb <cli_set_variable+8>: mov %rsi,-0x10(%rbp)
0x0000000100008ecf <cli_set_variable+12>: mov $0xff00ff00ff00ff,%rax
0x0000000100008ed9 <cli_set_variable+22>: pop %rbp
0x0000000100008eda <cli_set_variable+23>: retq
Ezert nem fontos a returnre adott gcc warning.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
de memoriacim konstanst azert akkor illik unsignedkent (unsigned long) megadni
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
buffer overflow
- A hozzászóláshoz be kell jelentkezni
Ez nem bof, pont az ellenkezoje, raadaskent a castolas lemaradt amiert biztos sirt erosen a fordito.
Jah -> return (void*)0x00ff00ff00ff00ff;
Nem ertem miert gondoljak az emberek, hogy a fordito hulyeseget pofazik. Az a fordito pont azert warning-ol, mert faszsagot csinalsz, vagy ha nem faszsagot csinalsz, akkor szarul csinalod.
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
0x0000000100008ecf <cli_set_variable+12>: mov $0xff00ff00ff00ff,%rax
Emiatt a sor miatt erdektelen az, h mit rinyal a return-re a compiler. A problemam _nem_ ebbol fakadt es _nem_ itt volt. A mov magasrol tesz arra, h milyen elojele van vagy nincs egy adott konstansnak, a regiszter szinten nem foglalkozik vele. Az elojel csak az adat ertelmezesetol fuggo kerdes.
BoF-nak meg azert BoF, mert egyeb mas cim (eredetileg egy lefoglalt memoria terulet kerult returnre) elojellel kiegeszitve tok random helyre mutato pointer lesz belole.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Bocsánat, a
void*
milyen típus is pontosan?
Nem arról szól a dolog -- persze, tévedhetek is -- hogy a definíciónál még nem lehet tudni, hogy milyen típust is ad vissza a függvény, viszont a függvény meghívásánál illene erről egy cast-olással nyilatkozni?
G.
============================================
"Share what you know. Learn what you don't."
- A hozzászóláshoz be kell jelentkezni
Lényegében de, viszont itt nem a void-on, hanem a mögötte lévő *-on van a hangsúly. Ő a kódjában int-et cast-ol void*-ra
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
S akkor a konverzió int-ről void*-ra és void*-ról int-re automatikusan megy végbe, vagy asszimetrikus a dolog?
G.
============================================
"Share what you know. Learn what you don't."
- A hozzászóláshoz be kell jelentkezni
Majdnem. A gond az volt, h egy kedves huzaskent a void*-ot lekasztolta nekem int-re es ezert nott oda a cltq.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Ne haragudj, k.rég volt amikor C-t és egyéb, 3. generációs nyelveket tanulgattam, ezért is nem mertem leírni, de ahogy elnézem, mások is valami hasonló nézeten vannak: van egy függvényed, ami visszaad valamilyen típust. Van a returnben egy konstans értéked. Ilyenkor a fordító azt csinálja, hogy kitalál a konstans értékhez egy általa feltételezett típust, azt konvertálja a függvényed visszatérési értékeként megjelölt típusra és így adja vissza a returnbe írt értéket. (feltéve, hogy a mai fordítók is nagyjából úgy működnek e téren, mint húsz évvel ezelőtti társaik)
Végeredményben ez a szokásos: "a számítógép nem a kívánságaid, hanem az utasításaid szerint működik" esetének tűnik.
De összeszedem magam, hogy megpróbáljak valami assembly listát kipréselni a gcc-ből (remélem, még lehet :D) és megnézem, hogy különböző variációkra hogy reagál.
Régen imádtam ilyenekkel szórakozni, sajnos nagyon kiestem belőle. :(
- A hozzászóláshoz be kell jelentkezni
Leginkabb azert rugoztok ezen a jelentektelen aprosagon, mert nem igazan ertitek, h hogyan mukodik a cdecl calling convention x86-on.
Egyszeru adat tipusok visszateresi ertekei igy alakulnak x86_64-en:
[unsigned] char : al
[unsigned] short : ax
[unsigned] int : eax
[unsigned] long: rax
float : st(0)
double : st(0)
void * : rax
akarmi * : rax
A topic inditoban leirt fuggveny x86_64 asm kodja innentol annyi, h
mov $0xff00ff00ff00ff,%rax
. Igy tok mindegy mit mire kellene castolni, attol meg minden esetben az elobbi asm kodra fog lefordulni a kod. Ha unsigned long lenne a fuggveny visszateresi ertekenek tipusa akkor is, ha long lenne, akkor is, ha int *, akkor is, ha void *, akkor is. A fuggveny visszateresi erteke 64 bites szamok eseten (ami lehet egy konstans, egy pointer, barmi) a rax-ban lesz megtalalhato, az ebben talalhato szam ertelmezese csak a kod tovabbi reszetol fugg. Ami viszont a fuggveny jo es normalis mukodese utan szepen a cltq-nak koszonhetoen ugy lett kezelve, mintha egy szimpla int lett volna a visszateresi ertek tipusa egy pointer helyett, teljesen fuggetlenul attol, h en ott egy allokalt memoriaterulet cimet vagy egy konstanst adok vissza.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Igen, ertem en hogy egy cltq -val tobb lett, de azt tessek mar megerteni, hogy egy kibaszott signed int-et adtal neki, hogy konvertalja void*-ra. Megtette, szar is lett, de errol nem a gcc tehet, hanem te.
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Attol meg, h folyamatosan ugyanazt a baromsagot szajkozod egyre aggresszivabban meg nem lesz igaz. Ha vegre ertelmezned azt a kibaszott asm dumpot, h mire fordult le az a kibaszott fuggveny, akkor latnad is miert.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Vagyis hulye vagyok en, hulye a fordito is mikor szol hogy integert adsz pointerkent (makes pointer from integer without a cast), es hulye mindenki mas is.
Ertem en, rendben:)
Az meg hogy erre forditotta, nem meglepo, mivel ez meg csak nem is kiszervezett konstans, nyugodtan optimalizalhatja forditas idoben
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Nem értem mit nem értesz, még én is értem. :) Ha a castolás (hiánya) miatt van ott a cltq, akkor annak a függvény asm kódjában kellene szerepelnie, még a ret előtt. Miután megvolt a ret, akármi is van a %rax-ban, azt onnantól kezdve void *-ként kell kezelni, függetlenül attól, hogy inttel lett inicializálva. Azonban a gcc ügyesen berakott egy cltq-t a callq után, mintha a visszatérési érték int lenne, pedig nem.
- A hozzászóláshoz be kell jelentkezni
Azért mert visszatérési értékként ő int-et adott, hibásan, majd stack pop után a másik oldal foghatja a fejét
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Ez C, itt nincs dinamikus típus. Minden adatot úgy értelmezünk, ahogy adott ponton épp megadtuk a statikus típust. Ha a függvény void *-ot ad vissza, akkor az ott void *.
- A hozzászóláshoz be kell jelentkezni
Ki beszelt dinamikus tipusrol? Void* meg csak nem is tipus
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Amikor arról beszéltél, hogy a callq után a kapott adat egy int, akkor feltételeztem úgy gondolod, hogy a fordító megjegyezte, hogy milyen típussal lett inicializálva az adat. Oké, ez nem teljesen az, mint ami pl. C++ esetén történik, de olyasmi.
Dehogynem típus, úgy hívják pointer.
- A hozzászóláshoz be kell jelentkezni
Nem: a pointer az pointer, ami nem típus, a void pl típus, még ha tipizálatlan is. A pointer típus egy olyan pointer, aminek meg van határozva a típusa, pl char*.
Bovebben: http://en.wikipedia.org/wiki/C_data_types#Pointer_types
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Jó persze, de a memóriában az összes pointer ugyanúgy néz ki, és mivel a memóriában reprezentálva van, ebből következően mégiscsak valamiféle típus.
- A hozzászóláshoz be kell jelentkezni
A memóriában minden ugyanúgy néz ki, csupa egy és nulla:D
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Ugye az megvan, h mivel regiszterben jon vissza a visszateresi ertek, ezert a regiszter pop szart se szamit ? :)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Tenyleg ennyire problemas a szovegertes ? :) Nem az a problemam, h beszol a compiler, h konstanst adok vissza egy pointernel es ezert warningol, amiben igaza is van (mellesleg ha lekasztolom void *-ra, akkor meg warning sincs), hanem h utana kurta el a tortenetet. Gondolom az is megvolt, h szandekosan -O0-lal forditottam.
Csak a kedvedert:
aeryn:asd pontscho$ cat main.c
void *basz(void)
{
return 1;
}
aeryn:asd pontscho$ gcc -c -o main.o main.c -O0 -Wall
main.c: In function 'basz':
main.c:4: warning: return makes pointer from integer without a cast
aeryn:asd pontscho$ otool -tv main.o
main.o:
(__TEXT,__text) section
_basz:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp,%rbp
0000000000000004 movq $0x0000000000000001,%rax
000000000000000e movq %rax,0xf0(%rbp)
0000000000000012 movq 0xf0(%rbp),%rax
0000000000000016 movq %rax,0xf8(%rbp)
000000000000001a movq 0xf8(%rbp),%rax
000000000000001e popq %rbp
000000000000001f ret
aeryn:asd pontscho$
---
aeryn:asd pontscho$ cat main.c
void *basz(void)
{
return (void *)1;
}
aeryn:asd pontscho$ gcc -c -o main.o main.c -O0 -Wall
aeryn:asd pontscho$ otool -tv main.o
main.o:
(__TEXT,__text) section
_basz:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp,%rbp
0000000000000004 movq $0x0000000000000001,%rax
000000000000000e movq %rax,0xf0(%rbp)
0000000000000012 movq 0xf0(%rbp),%rax
0000000000000016 movq %rax,0xf8(%rbp)
000000000000001a movq 0xf8(%rbp),%rax
000000000000001e popq %rbp
000000000000001f ret
aeryn:asd pontscho$
---
aeryn:asd pontscho$ cat main.c
#include <stdlib.h>
void *basz(void)
{
return malloc(1);
}
aeryn:asd pontscho$ gcc -c -o main.o main.c -O0 -Wall
aeryn:asd pontscho$ otool -tv main.o
main.o:
(__TEXT,__text) section
_basz:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp,%rbp
0000000000000004 subq $0x10,%rsp
0000000000000008 movq $0x0000000000000001,%rax
0000000000000012 movq %rax,%rdi
0000000000000015 callq 0x0000001a
000000000000001a movq %rax,0xf0(%rbp)
000000000000001e movq 0xf0(%rbp),%rax
0000000000000022 movq %rax,0xf8(%rbp)
0000000000000026 movq 0xf8(%rbp),%rax
000000000000002a addq $0x10,%rsp
000000000000002e popq %rbp
000000000000002f ret
aeryn:asd pontscho$
Capisce? Szoval hagyjuk mar ezt a faszsagot es kezdjunk mar el gondolkodni is vegre.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Gondolkodtam, es el van kurva sok minden;)
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Nehez annyit mondani, h "bocs, beneztem egy kicsit" amire en csak annyit mondanek, h "ugyan, semmi gond, mindenkivel elofordul" ? :)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Bocs, beneztem egy kicsit, csak tenyleg felreertheto amit irtal, viszont ha forditgatok magamnak akkor leesett volna:)
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
No prob, neztem mar be ennel durvabban is dolgokat. :)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Vagyis hulye vagyok en, hulye a fordito is mikor szol hogy integert adsz pointerkent (makes pointer from integer without a cast), es hulye mindenki mas is.
Sot, mondok jobbat, "tortem" anno ugy darwin/arm-on kamera modult, h indirekt cimzessel, egy fuggveny pointernek beirtam egy konstanst es utana azt hivogatta utana a kod. :-)
makes pointer from integer without a cast
Lasd a keretes bejegyzest.
nyugodtan optimalizalhatja forditas idoben
Nem optimalizalta ki mar a BaT altal irtak es a -O0 miatt sem. :)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Ebbol gondoltam a "kioptimalizalta" reszt:
return 0x00ff00ff00ff00ff;
mov $0xff00ff00ff00ff,%rax
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Az csak szam kiiras kulonbsegebol adodik, a leading nullakat csak azert szoktam kiirni, h vezesse a szemet.
0x00ff00ff00ff00ff (8 octet) == $0xff00ff00ff00ff (7 octet)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Jaja, most esett le nekem is, csak annyit neztem hogy ez nem egyezik:D
Nah jol van, azt hiszem aludnom kene, mert agressziv es bamba vagyok, ez meg nem jo kombo mint ahogy a mellekelt abra is mutatja
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Én inkább gyakorlati egyed vagyok, kipróbáltam: ubin (ubi64, mint32 bit) ugyan pofázik a gcc a casting hiánya miatt, de ha a return-be odaírsz egy (void *)0x...-t, a legyártott assembly kód bitről-bitre azonos marad.
Viszont azt a cltq-t sehol sem látom benne.
- A hozzászóláshoz be kell jelentkezni
Viszont azt a cltq-t sehol sem látom benne.
Szerinted miert voltam ideges ? :)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Én úgy értettem, hogy attól, hogy ott van. :)
- A hozzászóláshoz be kell jelentkezni
Igen, attol. A fuggveny eredetileg allokalt egy memoria teruletet ami a visszateres utan fel lett szabaditva es a cltq-nak koszonhetoen sig11-et dobott, teljesen jogosan. :)
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Mondd, az a logbejegyzés nálad hogy keletkezik??
Debug program írja ki vagy te íratod ki printf-fel?
Utóbbi esetben milyen formátumot adtál meg?
Mint mondtam, rohadt rég foglalkoztam C-vel, akkor még nem volt 64 bit, sem "%32lx" formátum string... :)
update: Ja, hogy volt valami crash is... akkor nem szóltam, csak nem értem. Ugyanis nálam még normálisan működik (látszólag).
- A hozzászóláshoz be kell jelentkezni
Nem relevans az a log fuggveny, mert meg elotte tortent a magia. Nem tudom milyen csillagallas kellett hozza, de osszejott.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Csak azért kérdeztem, mert amikor printf("%32x\n",...); próbáltam kiíratni a visszaadott értéket, akkor ugyanígy, jóval rövidebb értéket kaptam a visszaadottnál. Aztán kicseréltem az x-et lx-re és máris csodát láttam. :)
- A hozzászóláshoz be kell jelentkezni
Detto:D
Kicsit felrevezeto a post, de igy mar rajottem;)
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
O egy void* fgv.-t definialt, ami egy tipizalatlan Pointer. Ebben az esetben egy pointerrel kell visszaterni minden esetben (es itt most lenyegtelen hogy az a pointer egy int, char tipusu, vagy tipizalatlan void). Ezzel szemben, egy fixen hakolt integer-el ter vissza (a 0 integer, 0.0f float, a 0x0 meg egy hexakent definialt integer). Itt egyertelmu, hogy nem a gcc a hulye, leven szolt is neki, hogy nem szokas integerel pointerkent visszaterni
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Nem! Te voltal az aki egy integer-t castoltal egy pointer-re, a gcc ezert sirt. A szam az mindig szam lesz gcc-ben, a 0x meg bazira szam reprezentalas hexadecimalisan, ami meg mindig integer, raadaskent signed.
Raadaskent pont ezert nem a GCC csinalja az invalid pointert, hanem te.
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Gondolom ennek a hozzaszolasnak az ertelmezese es a c-ben hasznalt alap call conv. ismeretenek hianya akadalyoz meg abban, h ezen a marhasagon vegre tullepjunk.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Vitadonto otlet: a clang minek forditja? ;)
- A hozzászóláshoz be kell jelentkezni
Warningnak. :)
- A hozzászóláshoz be kell jelentkezni
Sajnos mivel meloban futottam bele es haladni kell ezert inkabb maskepp lett megoldva a problema, nem volt idom szarra nyomozni, h abban a kodhalmazban mi volt a hiszti oka.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
El szabad mondani, hogy hogyan oldottad meg/kerülted ki a problémát?
_____________________________
Powered by 1,3,7-trimetilxantin
- A hozzászóláshoz be kell jelentkezni
Clangom nincs, de van visual studio. :)
Kód:
#include <stdio.h>
void * cli_set_variable(char *var, char *val)
{
return 0x00ff00ff00ff00ff;
}
int main(void)
{
void *ret = cli_set_variable(NULL, NULL);
printf("%p", ret);
return 0;
}
Asm (aláhúzva a függvény és annak meghívása):
; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.21005.1
include listing.inc
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
_DATA SEGMENT
$SG3059 DB '%p', 00H
_DATA ENDS
PUBLIC cli_set_variable
PUBLIC main
EXTRN printf:PROC
pdata SEGMENT
$pdata$main DD imagerel $LN3
DD imagerel $LN3+42
DD imagerel $unwind$main
pdata ENDS
xdata SEGMENT
$unwind$main DD 010401H
DD 06204H
xdata ENDS
; Function compile flags: /Odtp
_TEXT SEGMENT
ret$ = 32
main PROC
; File c:\users\bat\temp\test.c
; Line 9
$LN3:
sub rsp, 56 ; 00000038H
; Line 10
xor edx, edx
xor ecx, ecx
call cli_set_variable
mov QWORD PTR ret$[rsp], rax
; Line 12
mov rdx, QWORD PTR ret$[rsp]
lea rcx, OFFSET FLAT:$SG3059
call printf
; Line 13
xor eax, eax
; Line 14
add rsp, 56 ; 00000038H
ret 0
main ENDP
_TEXT ENDS
; Function compile flags: /Odtp
_TEXT SEGMENT
var$ = 8
val$ = 16
cli_set_variable PROC
; File c:\users\bat\temp\test.c
; Line 4
mov QWORD PTR [rsp+16], rdx
mov QWORD PTR [rsp+8], rcx
; Line 5
mov rax, 71777214294589695 ; 00ff00ff00ff00ffH
; Line 6
ret 0
cli_set_variable ENDP
_TEXT ENDS
END
Eredmény:
C:\Users\BaT\Temp>cl test.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
test.c(5) : warning C4047: 'return' : 'void *' differs in levels of indirection from '__int64'
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
C:\Users\BaT\Temp>test.exe
00FF00FF00FF00FF
C:\Users\BaT\Temp>
- A hozzászóláshoz be kell jelentkezni
sub.
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Deklaráltad a cli_set_variable függvényt a hívás helye előtt? A generált kód alapján nem úgy néz ki...
- A hozzászóláshoz be kell jelentkezni
Szerintem is ez lesz a gond: nem volt prototípus, 4-byte-os integert alaptértelmezett a fordító, azt terjesztette ki pointerré (azért előjelkiterjesztéssel, mert a programok 64-bites módban a címtartomány legalját és legtetejét szokták használni: lásd itt az ábrát)
Egyébként még a fv-ben is kitennék egy-két L-betűt:
return 0x00ff00ff00ff00ffLL;
sőt:
return (void *)0x00ff00ff00ff00ffLL;
PS: Mondjuk az is igaz, hogy jobb helyen addig nem is foglalkoznak egy ilyen "hibával", amig a fordítás nem warningmentes (nem, nem a warningok elnyomására gondolok, hanem a -W -Wall -Wextra -pedantic uniójára)
- A hozzászóláshoz be kell jelentkezni
Egy kave kozben nekem is eszembe jutott ez, aztan kiderult, h igen.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Akkor kérj elnézést a GCC-től, mert ezek szerint nem ők hibáztak!
- A hozzászóláshoz be kell jelentkezni
Deklaráltad a cli_set_variable függvényt a hívás helye előtt?
Ugy ertem, igen, deklaráltam a függvényt a hívás helye előtt.
---
pontscho / fresh!mindworkz
- A hozzászóláshoz be kell jelentkezni
Oh, félreértettem.
- A hozzászóláshoz be kell jelentkezni
Mi volt végül a hiba oké? Csak nem PEBKAC?
- A hozzászóláshoz be kell jelentkezni