Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding
You last visited: Today at 07:22

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



inline ASM, error C2415: improper operand type

Discussion on inline ASM, error C2415: improper operand type within the General Coding forum part of the Coders Den category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Nov 2011
Posts: 6
Received Thanks: 0
inline ASM, error C2415: improper operand type

This is how the native function looks like:
Code:
006952E9 - 8B 44 24 04                - mov eax,[esp+04]
006952ED - 89 41 20                   - mov [ecx+20],eax
006952F0 - C2 0400                    - ret 0004
Now this is how my hook for this function looks like:
Code:
void Naked NewCooldown()
{
	__asm
	{
		MOV dwCooldown, [ESP+0x04]
		MOV [ECX+0x20], dwCooldown
		RET 4
	}
}
I would like to store value of [ESP+0x04] in DWORD variable 'dwCooldown' but i am getting an error:
Code:
error C2415: improper operand type
can I count on your help?
cAddict is offline  
Old 11/17/2011, 14:20   #2
 
link's Avatar
 
elite*gold: 1
Join Date: Jul 2005
Posts: 553
Received Thanks: 451
Trying to access two memory addresses in one instruction is invalid.
Also, in 32-bit ret is just an alias for retn.

Code:
void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown],EAX
		MOV [ECX+0x20],EAX
		RETN 4
	}
}
link is offline  
Thanks
1 User
Old 11/17/2011, 14:50   #3
 
elite*gold: 0
Join Date: Nov 2011
Posts: 6
Received Thanks: 0
thanks link, but now i've got another problem, omg.

Code:
char chCooldownInfo[0] = "Cooldown value: %d\n";
void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX

		// trying to push EAX on stack as a variable for chCooldownInfo
		// EAX already hold the value so there is no need to copy dwCooldown on stack, right?
		PUSH EAX
		MOV EAX, OFFSET chCooldownInfo
		PUSH EAX
		CALL printf

		// clean up the stack
		POP EBX
		POP EBX

		// return
		RETN 4
	}
}
Code:
void CooldownHandler()
{
	char chCooldownInfo[] = "cooldown value: %d\n";

	__asm
	{
		MOV EAX, [dwCooldown]
		PUSH EAX
		MOV EAX, OFFSET chCooldownInfo
		PUSH EAX

		CALL printf

		POP EBX
		POP EBX
	}
}

void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX
		CALL CooldownHandler
		RETN 4
	}
}
I've tried both ways, both fail.

What I want to do is to print to console value of dwCooldown everytime my Cooldown hook is being executed but this code crash my game client.

edit:
i am getting really confused about asm. now im getting another error on:
Code:
		MOV EAX, OFFSET chCooldownInfo
error C2415: improper operand type
while this is working perfectly fine:
Code:
#include "stdafx.h"
#include "stdio.h"
#include "process.h"

char chFormat[] = "%s %d\n";
char chValue[] = "value:";
int	 iValue = 652;


int main( void )
{
   __asm
   {
      mov  eax, [iValue]
      push eax
      mov  eax, offset chValue
      push eax
      mov  eax, offset chFormat
      push eax

      call dword ptr [printf]

      pop  ebx
      pop  ebx
      pop  ebx
   }

   system("pause");
}
what is going on? oO
cAddict is offline  
Old 11/17/2011, 18:05   #4
 
link's Avatar
 
elite*gold: 1
Join Date: Jul 2005
Posts: 553
Received Thanks: 451
Cleaning the stack by overwriting a 'sensitive' register like ebx (it could still hold some value important to the caller) isn't the best way.
In case of calling a cdecl-function just increment esp by the amount of bytes you have pushed before and are meant as parameters (printf gets 2 dwords as params -> add esp,8).

Either define chCooldownInfo as a global variable and use "offset chCooldownInfo" or define it inside a function to make it exist on the stack as long as the function itself gets executed and use "lea eax,[chCooldownInfo]".
In the latter case chCooldownInfo is just a pseudo-label for sth like ebp-4, therefore its address has to be calculated, in the former chCooldownInfo is an absolute label, means "push offset chCooldownInfo" would be like "push 00400210h"

Try this:
Code:
void Naked NewCooldown()
{
	char chCooldownInfo[] = "Cooldown value: %d\n";
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX

		PUSH EAX
		LEA EAX,[chCooldownInfo]
		PUSH EAX
		CALL printf

		ADD ESP,4*2

		RETN 4
	}
}
EDIT:
ah, and as far as I recall you have to call API functions in this manner "call dword ptr [printf]" as no jump-table gets generated and printf is the address of an IAT-entry which holds the function's actual address.
link is offline  
Thanks
1 User
Old 11/17/2011, 19:41   #5
 
elite*gold: 0
Join Date: Nov 2011
Posts: 6
Received Thanks: 0
great explanation, I really appreciate your help.

edit:
My hook is still crashing my game client just after 'printf' is being executed by now I got a point.
cAddict is offline  
Old 11/17/2011, 21:48   #6
 
link's Avatar
 
elite*gold: 1
Join Date: Jul 2005
Posts: 553
Received Thanks: 451
oops.. having a naked function with neither prologue nor epilogue and using local variable doesn't make sense..
The prologue actually adjusts esp and makes room for the local variables, thus declaring the function as naked but trying to access local variables is erroneous, didn't think of it..

Code:
char chCooldownInfo[] = "Cooldown value: %d\n";

void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX

		PUSH EAX
		PUSH OFSSET chCooldownInfo
		CALL dword ptr [printf]

		ADD ESP,4*2

		RETN 4
	}
}
or

Code:
void NewCooldown(int param)
{
	char chCooldownInfo[] = "Cooldown value: %d\n";
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX
	}
	printf(chCooldownInfo, dwCooldown);
}
hope this finally works...
link is offline  
Thanks
1 User
Old 11/17/2011, 22:38   #7
 
elite*gold: 0
Join Date: Nov 2011
Posts: 6
Received Thanks: 0
thank you for another educating reply.


however, first example cause an error in my compiler:
Code:
error C2400: inline assembler syntax error in 'first operand'; found 'newline'

and second one cause an engine crash at offset 'NewCooldown+46':
Code:
NewCooldown   - 83 EC 18              - sub esp,18
NewCooldown+3 - A1 00B00010           - mov eax,[__security_cookie]
NewCooldown+8 - 33 C4                 - xor eax,esp
NewCooldown+A - 89 44 24 14           - mov [esp+14],eax
NewCooldown+E - A1 60510010           - mov eax,[`string']
NewCooldown+13 - 8B 0D 64510010       - mov ecx,[`string'+4]
NewCooldown+19 - 8B 15 68510010       - mov edx,[`string'+8]
NewCooldown+1F - 89 04 24             - mov [esp+esp],eax
NewCooldown+22 - A1 6C510010          - mov eax,[`string'+C]
NewCooldown+27 - 89 4C 24 04          - mov [esp+04],ecx
NewCooldown+2B - 8B 0D 70510010       - mov ecx,[`string'+10]
NewCooldown+31 - 89 54 24 08          - mov [esp+08],edx
NewCooldown+35 - 89 44 24 0C          - mov [esp+0C],eax
NewCooldown+39 - 89 4C 24 10          - mov [esp+10],ecx
NewCooldown+3D - 8B 44 24 04          - mov eax,[esp+04]
NewCooldown+41 - A3 A0B80010          - mov [dwCooldown],eax
NewCooldown+46 - 89 41 20             - mov [ecx+20],eax   // this is the place that cause a crash
NewCooldown+49 - 8B 15 A0B80010       - mov edx,[dwCooldown]
NewCooldown+4F - 52                   - push edx
NewCooldown+50 - 8D 44 24 04          - lea eax,[esp+04]
NewCooldown+54 - 50                   - push eax
NewCooldown+55 - FF 15 A8500010       - call dword ptr [_imp__printf]
NewCooldown+5B - 8B 4C 24 1C          - mov ecx,[esp+1C]
NewCooldown+5F - 83 C4 08             - add esp,08
NewCooldown+62 - 33 CC                - xor ecx,esp
NewCooldown+64 - E8 AD300000          - call __security_check_cookie
NewCooldown+69 - 83 C4 18             - add esp,18
NewCooldown+6C - C3                   - ret

this asm code looks strange to me and its even more confusing
maybe this code is erasing some important registers?



maybe I should tell you few words on how this native function works
Code:
006952E9 - 8B 44 24 04                - mov eax,[esp+04]
006952ED - 89 41 20                   - mov [ecx+20],eax
006952F0 - C2 0400                    - ret 0004

// eax = 1140735489, 1144036829, and so on.
eax contains something like a timestamp+skill charge+cooldown, so game will know how long the cooldown should last.

these values are different from the one I can get by GetTickCount but every time I use skill value is increased by same amount:
current timestamp + (skill charge time + skill cooldown time)

now, if I patch this function like this:
Code:
006952E9 - C7 41 20 01000000          - mov [ecx+20],00000001
006952F0 - C2 0400                    - ret 0004
then it works perfectly and I get no cooldown at all so I can spam teens/houndreds of skills in a second.

The problem is this 'plain stupid patching' method does not satisfy me anymore and I want to learn something more 'sufisticated'


edit:
I have succeded to stop my game from getting a crash by 'PUSHAD/POPAD' - saving and restoring registers, so my code looks like this:
Code:
void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [ECX+0x20], EAX

		PUSH EAX
		MOV EAX, OFFSET info
		PUSH EAX

		PUSHAD
		CALL DWORD PTR [printf]
		POPAD

		ADD ESP, 0x08

		RETN 4
	}
}
but something must be wrong because instead of "cooldown value: %d" I get this:
Code:
ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(
~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý
(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~
ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ý(
~ý(~ý(~ý(~ý(~ý(~ý(~ý(~ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}ÉĆ}
cAddict is offline  
Reply


Similar Threads Similar Threads
i bot run time error 13 type mimatch
01/17/2011 - Silkroad Online - 2 Replies
i use i bot now for 3 days they send me some scripts at temple job cave with the scripts that they do the quest and then it finish it ... i go there it picking up the quest go at the training place it goes ba ck to turn in the quest BUT WHEN IT GOES BA CK AGAIN AT TRAINING PLACE AT THE SPOT I GET THE ERROR MSG ''RUN TIME ERROR 13 TYPE MISMATCH'' can someone pls help me with this i will be very appriciate it thank you !
[Ribot] Error 13 type mismatch
02/05/2010 - Silkroad Online - 2 Replies
If got the 'error 13 type mismatch'. I didn't got it before but I logged in to my char (I normally use clientless) and then I wanted to do clientless again and it gives that error. When I try to use bot + client it says error 6 overflow. I tried to install the ocx files again and reinstalled the bot. Still doesn't work! Anybody got the answer for this? Thanks in advance!
Error Code6 Type 412
11/20/2009 - Cabal Online - 5 Replies
i am search and search Cabal update and now comes Error Code6 Type 412 wenn iam loging in i get cabalrider but in the forum nothing for this error have everybody the same error Code what can i do
Have you experienced Error Code: 6 Type: 421 ?
06/17/2009 - Cabal Online - 2 Replies
Have you experienced Error Code: 6 Type: 421? Any known solutions for this one - whitout having to re-install the game? Thanks
Different type of error
04/09/2009 - Aion - 4 Replies
after installing both the torrent version and the multiple files from the chinese site this is the error i recieve after i click (Y) to install. http://img19.imageshack.us/img19/5062/75705188.jp g im useing vista x64 with all drivers updated. Now i did try the English clients offered in the FAQ thread, and it installs fine. but that's not for the chinese open beta. Can anyone give me a hand here?



All times are GMT +2. The time now is 07:22.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.