Wymuszenie inline'a Visual Studio 2003

0

Czołem Bracia

Mam sobie funkcje:

template<typename T> __forceinline T SET(T t)
{
	T o=t;
	o=~o;
	o^=50;
	o+=60;
	return o;
}
template<typename T> __forceinline T GET(T t)
{
	T o=t;
	o-=60;
	o^=50;
	o=~o;
	return o;
}

Po kompilacji w trybie release z poustawianymi flagami optymalizacyjnymi na full widzę w podglądzie asemblerowym,że za ch..a mi visual nie chce uhonorować inline'a,nawet __forceinline olewa tylko wylicza wartości wyrażeń i używa gotowców w rodzaju push -248 itp

Znacie na to jakąś radę?Bo póki co się nie dogóglałem :/

1

Może spróbuj volatile.

0

Ustawiłeś wszystkie opcje optymalizacji "na full" i teraz masz pretensje, że kompilator zoptymalizował program.. bardziej niż byś tego chciał :D?

Wywal z opcji kompilatora /O2, wstaw /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy i po kolei usuwaj po jednej, żeby sprawdzić, która z opcji odpowiada za ten rodzaj optymalizacji.

0

Cóż,zgodnie z zasadą nie kijem go to pałą,poradziłem sobie w taki sposób,że zdefiniowałem makra zamiast funkcji inline
Jednak używanie ich nie przynosiło do końca takiego rezultatu jak chciałem.Oto testowy program:

#include <iostream>
using namespace std;
/* Let's assume such operations were generated(in order of applying):
1.Bitwise negation
2.exlusive or with value 50
3.adding 60 
Macros for such combination have look:*/
#define SET(x) (((~(x))^50)+60)
#define GET(x) (~(((x)-60)^50))

int main(int argc, const char* argv[])
{
	int a;
//encryption start
	a=SET(257);
//encryption end
	cout<<"obfuscated a="<<a<<endl;
	cout<<"decrypted a(should be 257))="<<GET(a)<<endl;

	return 0;
}

Kompilacja w trybie release w włączoną flagą /Ox daje rezultat:
; 18 : int a;
; 19 : //encryption start
; 20 : a=SET(257);
; 21 : //encryption end
; 22 : cout<<"obfuscated a="<<a<<endl;

push	-248					; ffffff08H //**tutaj ładnie schowało wartość 257**
push	OFFSET FLAT:??_C@_0O@BJAKDLLP@obfuscated?5a?$DN?$AA@
push	OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add	esp, 8
mov	ecx, eax
call	??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov	esi, eax
push	10					; 0000000aH
mov	ecx, esi
call	?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov	ecx, esi
call	?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char> >::flush

; 23 : cout<<"decrypted a(should be 257))="<<GET(a)<<endl;

push	257					; 00000101H **a tutaj dupa jak Słońce widziane z orbity Merkurego,cały wysiłek włożony w ukrycie wystąpienia tej wartości w kodzie właśnie poszedł się yebać**
push	OFFSET FLAT:??_C@_0BN@BHBFMIJM@decrypted?5a?$CIshould?5be?5257?$CJ?$CJ?$DN?$AA@
push	OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add	esp, 8
mov	ecx, eax
call	??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov	esi, eax
push	10					; 0000000aH
mov	ecx, esi
call	?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov	ecx, esi
call	?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char> >::flush

Kombinowałem,góglowałem i w końcu okazało się,że Brat lukasz1235 miał rację-zmiana definicji na:

volatile int a;

daje asemblerowy kod:
; 18 : volatile int a;//volatile forces compiler to directly use memory cell instead of any precalculations
; 19 : //encryption start
; 20 : a=SET(257);

mov	DWORD PTR _a$[esp+8], -248		; ffffff08H **piękne schowanie rzeczywistej wartości i to jeszcze zoptymalizowane do stałej.Me like ^^ **

; 21 : //encryption end
; 22 : cout<<"obfuscated a="<<a<<endl;

mov	eax, DWORD PTR _a$[esp+8]
push	eax
push	OFFSET FLAT:$SG9676
push	OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add	esp, 8
mov	ecx, eax
call	??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov	esi, eax
push	10					; 0000000aH
mov	ecx, esi
call	?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov	ecx, esi
call	?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char> >::flush

; 23 : cout<<"decrypted a(should be 257))="<<GET(a)<<endl;

mov	ecx, DWORD PTR _a$[esp+8]                 //**a tutaj ślicznie rozwinięte i zoptymalizowane instrucje z makra GET bez ujawniania wartości**
sub	ecx, 60					; 0000003cH
xor	ecx, 50					; 00000032H
not	ecx
push	ecx
push	OFFSET FLAT:$SG9679
push	OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add	esp, 8
mov	ecx, eax
call	??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov	esi, eax
push	10					; 0000000aH
mov	ecx, esi
call	?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov	ecx, esi
call	?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ ; std::basic_ostream<char,std::char_traits<char> >::flush

HA!Żeby było weselej to okazuje się,że po dodaniu tego volatile do zmiennej a kompilator odzyskał znienacka umiejętność do prawidłowej interpretacji __forceinline! :O i teraz nie wywołuje mi funkcji callem tylko wrzuca jej ciało do kodu jak Swaróg przykazał.Jaja jak berety normalnie,a tak na poważnie to wie ktoś,czemu właśnie tak się dzieje?

0

spróbuj inline assembly...
i sam pochowaj wartości :)
btw. jeżeli robisz crackme to raczej nie stosuj takich technik - bardzo łatwo złamać taki "szyfr"

1 użytkowników online, w tym zalogowanych: 0, gości: 1