• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

## Recommended Posts

Hi im new to asm and as practice I wanted to write asm code wich call''s a function wich takes a string(type) as parameter. To learn how to do this I''ve made so that VS outputs an asm file whit c/c++ source in it. But im still unsure how to deal calls whit strings becose the allocator function and maybe others(well ya it''s a nested class structure all the way from basic_string) are needed before the string can be pushed.
// heres the simble code what im trying to turn in asm

void printstr(string str)
{
cout<<str<<endl;
}

int main()
{

string stri = "test string";
printstr(stri);

return 0;
}

// visual studio generated asm code starts here

; string stri = "test string";

lea	eax, DWORD PTR $T8697[ebp] push eax push OFFSET FLAT:??_C@_0M@MDMJ@test?5string?$AA@ ; string''
lea	ecx, DWORD PTR _stri$[ebp] call ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBDABV?$allocator@D@1@@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > mov DWORD PTR __$EHRec$[ebp+8], 0 ; printstr(stri); sub esp, 16 ; 00000010H mov ecx, esp mov DWORD PTR$T8698[ebp], esp
lea	edx, DWORD PTR _stri$[ebp] push edx call ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> >
mov	DWORD PTR -44+[ebp], eax
call	?printstr@@YAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ; printstr add esp, 16 // and ends here // what I''ve done so far is is: sub esp, 16 ; ok mov ecx, esp ; ok mov DWORD PTR$T8698[ebp], esp  ; huh T ?
lea	edx, DWORD PTR stri     ; ok
push	edx                     ; ok
call	??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > mov DWORD PTR -44+[ebp], eax ; 44 ? call printstr ; ok add esp, 16 ; and done As you can see I can''t figure whats the correct syntax for first call becose of that messy line full of symbols and other detail like that T... something to do whit templates I asume?  It would be great if some one could show how to code that c++ code to a asm! #### Share this post ##### Link to post ##### Share on other sites This ASM code is highly dirty.Find some program that deassembles an .EXE or type in the command like "-debug file.exe" and start debuggin'' "Tonight we strike,there is thunder in the sky,together we''ll fight,some of us will die,but they''ll always remember that we''ve made a stand and many will die by hand!" - ManOwaR #### Share this post ##### Link to post ##### Share on other sites Problem is in C++, it will be very, very... VERY hard to translate this simple c++ into ASM. Class''es arent something natural for ASM... IMHO it is a suecide About suecide... If i was you and i would be realy in need to have this small pice of code in assembly i would first write in C functions that do exacly what string class do but using only structures and other "tools" supported on clean C. Porting C to ASM is much simpler than C++, but simpler not simple anyway "Woman be my slave !!!" - ManOwaR #### Share this post ##### Link to post ##### Share on other sites quote: Original post by Estor Problem is in C++, it will be very, very... VERY hard to translate this simple c++ into ASM. Class''es arent something natural for ASM... IMHO it is a suecide About suecide... If i was you and i would be realy in need to have this small pice of code in assembly i would first write in C functions that do exacly what string class do but using only structures and other "tools" supported on clean C. Porting C to ASM is much simpler than C++, but simpler not simple anyway "Woman be my slave !!!" - ManOwaR Hey Estor,nice going with the "Pleasure Slave"!Hail and Kill! "Tonight we strike,there is thunder in the sky,together we''ll fight,some of us will die,but they''ll always remember that we''ve made a stand and many will die by hand!" - ManOwaR #### Share this post ##### Link to post ##### Share on other sites To Estor: That is my first and last solution. :/ Well is there an alternative way to call function like call address in asm? Or could I some way have pointer to the allocator function? Then calling would be easy! #### Share this post ##### Link to post ##### Share on other sites try to search for some c++ decompiler or diassembler....... #### Share this post ##### Link to post ##### Share on other sites Try getting a free compiler (GCC and MinGW come to mind) and use some of the compile options to compile to assembly which pretty much all of them should have (MinGW does so GCC definatly should msvc should but Im not sure.) #### Share this post ##### Link to post ##### Share on other sites Hi again. You say that get disassempler. Well I hapend to have one. But what im suposed to do whit, hack the exe? #### Share this post ##### Link to post ##### Share on other sites This problem is really bothering me... Could some one explain what should I do exactly? #### Share this post ##### Link to post ##### Share on other sites quote: Original post by Craazer You say that get disassempler. Well I hapend to have one. But what im suposed to do whit, hack the exe? Please look at the assembly listing in your disassembler. The good dasms even show you automatically where your procedures start. _Or_, compile with some good IDE (i recommend VS.net 2003) and request assembly listings at compiler settings. Usually, you get the symbolic info as well (var&func names) when using this method. EDIT: I think all compilers support assembly listings, not just the ones with IDE EDIT 2: Yohumbus already offered this option, sorry! [edited by - Nik02 on August 9, 2003 12:21:08 PM] [edited by - Nik02 on August 9, 2003 12:23:35 PM] #### Share this post ##### Link to post ##### Share on other sites quote: Original post by Nik02 quote: Original post by Craazer You say that get disassempler. Well I hapend to have one. But what im suposed to do whit, hack the exe? Please look at the assembly listing in your disassembler. The good dasms even show you automatically where your procedures start. _Or_, compile with some good IDE (i recommend VS.net 2003) and request assembly listings at compiler settings. Usually, you get the symbolic info as well (var&func names) when using this method. EDIT: I think all compilers support assembly listings, not just the ones with IDE EDIT 2: Yohumbus already offered this option, sorry! [edited by - Nik02 on August 9, 2003 12:21:08 PM] [edited by - Nik02 on August 9, 2003 12:23:35 PM] Hi Nik02. Im using VS studio 6.0 and I have the assembly listin option enabled. And when I look at part printstr(stri); (as showed in my first post) I see lot of symbols and mess behind the call as also showed in the first post. Wich leads to the problem: call ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> >mov	DWORD PTR -44+[ebp], eaxcall	?printstr@@YAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ; printstr// quite a mess huh?//I can turn last call look like this so it compiles:call printstr// but I dont know the actual identifier of the first call. #### Share this post ##### Link to post ##### Share on other sites Because of C++'s support for classes, namespaces, and function overloading, every symbol name (functions & variables) has to be 'decorated', to produce a unique name in assembly. Now, since there is no standard way to do this, different compilers do it differently. This is why you can't simply type call printstr in asm. There is a means to avoid this, however: declare your printstr function as extern "C" void printstr(string str). Then, in asm, it will be called _printstr. Your next problem is with classes. I don't recommend trying to pass class types by value in asm; references are much easier to deal with. So, change your function definition to extern "C" void printstr(const string& str) Next, you need to create a string object in your assembly function. To do this, you will need to find the exact size of a std::string. Then, allocate that much space on the stack. Load the address of that space into the ecx register. Then, call the default constructor. From the disassembly you gave, that is called ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z. Unfortunately, there is no way to avoid using mangled names when dealing with class methods. Now, you need to call operator= with the address of a string literal, and the address of your string object still in ecx. This operator is called ??4?$basic_string@DV?$char_traits@D@_STL@@V?$allocator@D@2@@_STL@@QAEAAV01@PBD@Z in VC++ 6 with STLPort, or (I think) ??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z with the default STL. Remember, you need to clear its argument off the stack afterwards, so add 4 (the size of a pointer) to the esp register. Now, you should have a std::string object on the stack, containing whatever text you gave it. Next, to call your function with it.

This is the (relatively) easy part. Push the address of your string object onto the stack, then call _printstr. Again, remember to add 4 to esp` afterwards to clear the argument from the stack.

I haven't dealt with any function prologue/epilogue you may need if you're intending to call your ASM function from C/C++. That bit is fairly simple, though. Of course, the whole business isn't helped by all the template expansions; it would be much easier with a simpler, less flexible string class that isn't templated. I haven't tested this yet, but I hope it is helpful.

[EDIT: I'm assuming you're using MASM or similar for the assembly code, and not VC++'s inline assembler. I'm not sure whether that likes you using decorated names.]

[edited by - sbennett on August 10, 2003 12:50:33 PM]

##### Share on other sites
On trying this out, it appears that the default constructor for std::string needs to be passed an allocator object. I should be able to tell you how to do it in a couple of minutes, unless I am called away...

[EDIT] I'm sorry, but the STL has defeated me. I may be able to get a simpler example working for you, but I have to stop right now.

[edited by - sbennett on August 10, 2003 1:54:20 PM]

##### Share on other sites
quote:
Original post by sbennett

I''m sorry, but the STL has defeated me. I may be able to get a simpler example working for you, but I have to stop right now.

I agree with sbennett. It seems STL with classes can generate surprisingly effective scramble code!
Makes me wonder why people don''t use it for pirate protection

So, Craazer, i suggest rewriting the logic yourself... after thinking it over, of course.

rgds Nik

• ### Forum Statistics

• Total Topics
627700
• Total Posts
2978693

• 21
• 14
• 12
• 10
• 12