• Welcome to Valhalla Legends Archive.
 

Some sort of delay code needed!

Started by Paul, February 17, 2004, 05:36 AM

Previous topic - Next topic

Paul

I'll start by explaining my problem and things I've tried.

I'm writing a Cursor Attack hack for Diablo II. It works for all technical purposes, but because the cursor highlight routine I'm using is called roughly 200 times a second when I highlight a monster to grab its ID, name and send the attack data it's sending my packet data to the realm server way too fast -- at a rate of 200 packets a second, thus causing a ban for flooding the server with godly amounts of data in a short period of time.

Anyway, my solution for solving this packet flooding issue was to create some sort of timer, but I soon realized after compiling my code that it wouldn't work. It would only lag the client down, which it did AND still sent enormous amounts of data in a short period of time.  Here is what I did though:


#Packet delay code
Some D2 send() address here
jmp @ start

#start
cmp byte ptr [ecx], 0d // Attack packet
je @ settime
cmp byte ptr [ecx], 3c // Switch skill packet
je @ settime
jmp @ end

#delay1
dec eax
cmp dword ptr eax, 00000000
je @ end
jmp @ delay1

#settime
mov dword ptr eax, 00002000
jmp @ delay1

#end
return codes here



Instead, the other solution that presented itself to me was to hook the send() in the D2 client again and code something that did the following because the timer code I tried isn't working:

If data is passed to the send() too quickly, destroy that data and exit send()

I can't think of any way of doing this in ASM at the moment... Any suggestions?

Edit:
Another way of putting it would be, how would I write some sort of wait-time code before a function can be called again?

iago

You could use an api settimer() function that auto-resets to call your code once/second or something like that.  That may be the easiest way.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Adron

You could also store the value of GetTickCount and check current GetTickCount against stored when your routine is called - only continue (and store new GetTickCount) if X ms have passed.

Paul

Is there a way of doing it without using Windows APIs? An example of something you could show me in ASM would be greatly appreciated.

Adron

Quote from: Paul on February 17, 2004, 04:51 PM
Is there a way of doing it without using Windows APIs? An example of something you could show me in ASM would be greatly appreciated.

You could skip doing anything except every X times it is called. That won't be very accurate though. You should use Windows APIs.

Paul

#5
Quote from: Adron on February 17, 2004, 04:54 PM
You could skip doing anything except every X times it is called. That won't be very accurate though.

I never thought of doing it that way, thanks!  ;)

Edit:
Works! Here is what I did:


dec eax
cmp dword ptr eax, 00000000
jne @ nono

#settime
mov dword ptr eax, 50000000

#do action
call more code

#nono
kill it code down here + return

iago

The only problem with that is that it's computer-dependant.. it won't necessarely work at that speed on other computers.  At least, if you were using the windows API, it would be consistant across windows computer.  And d2 won't run on anything besides windows, so life would be good.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Yoni

#7
Optimization police.

Quote from: Paul on February 17, 2004, 05:05 PM
dec eax
cmp dword ptr eax, 00000000
jne @ nono


The second line (cmp) is not necessary.
If dec reduces its argument to zero, it sets ZF, the zero flag (which is the same as the "equal" flag - jz and je are the same instruction, as well as jnz and jne).
So you could just use:

dec eax
jnz @ nono


Also, in general cases (i.e. not immediately following an instruction like dec), instead of "cmp eax, 0" you should use "test eax, eax" (or other registers) - does the same thing, either faster or with smaller code (or both).

Edit: Punctuation  ::)

iago

I tend to use test eax,eax because that's what I see in most compiled code :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Adron

I like to use cmp for clarity when I'm really testing for the explicit value of zero, and not writing anything critical. Much like using if(a) vs if(a == 0), although in a high level language it hopefully makes no difference to the generated code.

iago

Quote from: Adron on February 18, 2004, 06:03 PM
I like to use cmp for clarity when I'm really testing for the explicit value of zero, and not writing anything critical. Much like using if(a) vs if(a == 0), although in a high level language it hopefully makes no difference to the generated code.

It depends which language; Java can *only* accept booleans inside if, so if(a) causes a compile error.  That's often very frustrating, but it does add clarity.  

I've never seen "test" used for anything besides "test eax, eax" or the like; what's it actually used for?
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


K

Quote from: iago on February 18, 2004, 08:05 PM
It depends which language; Java can *only* accept booleans inside if, so if(a) causes a compile error.  That's often very frustrating, but it does add clarity.  

I've never seen "test" used for anything besides "test eax, eax" or the like; what's it actually used for?

"Test performs a logical and on its two operands and updates the flags (CF, OF).  Neither destination nor source is changed."

http://202.114.22.131/mirrors/www_litespeed_org/Tutorials/Drme2.htm#TEST

iago

Quote from: K on February 18, 2004, 08:12 PM
Quote from: iago on February 18, 2004, 08:05 PM
It depends which language; Java can *only* accept booleans inside if, so if(a) causes a compile error.  That's often very frustrating, but it does add clarity.  

I've never seen "test" used for anything besides "test eax, eax" or the like; what's it actually used for?

"Test performs a logical and on its two operands and updates the flags (CF, OF).  Neither destination nor source is changed."

http://202.114.22.131/mirrors/www_litespeed_org/Tutorials/Drme2.htm#TEST

Doesn't it affect the ZF?  Since generally a jz or jnz are used afterwards.

And how is that different from cmp?  Is cmp an or?
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Kp

Quote from: iago on February 18, 2004, 08:17 PMAnd how is that different from cmp?  Is cmp an or?

cmp determines an arithmetic relation between the two operands (which is greater/less).  test determines the bit relation between the two operands (whether there are any bits enabled in both of them).
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

iago

Quote from: Kp on February 18, 2004, 10:02 PM
Quote from: iago on February 18, 2004, 08:17 PMAnd how is that different from cmp?  Is cmp an or?

cmp determines an arithmetic relation between the two operands (which is greater/less).  test determines the bit relation between the two operands (whether there are any bits enabled in both of them).

aah, ok, so test doesn't care about nearly as many different things.  So you can't use a test then jle, and such?

This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*