Kernelmode aimbot

Technical Discussions not Related Directly to MHS. For Example, Coding, Hex Editing, General Hacking, Etc.

Moderators: g3nuin3, SpeedWing, WhiteHat

Kernelmode aimbot

Postby troublesh00ter » Sat Sep 12, 2009 12:19 am

I am currently working on developing an aimbot that is fully running in ring 0. I have decent understanding of driver development, mostly learning through curiosity and then getting shot down by 'Don Burn' for asking a question that will make my driver CRAP ;).

Anyway to get to the point. I have the necessary position and angle offsets of me and the opponents. The problem is now that the positions are floats and there is no support for floating point operations in the kernel. I've read about some hacks around this to get access to the FPU registers but I don't feel like that is the way to go.

I've thought about some ways to overcome this problem but I'm really having problems deciding which way to and I hope you can help me break it down. Here are some of my ideas:

- For each FPO (Floating point operation) we could use a usermode call to do it for us.

* Will (probably) have a significant effect on performance. We could get all of the FPO results with one call to usermode but still that will be about ever 30 ms(rough guess, no hard value yet as to how often the aimbot loop needs to 'update').

- Create a look up table for functions like atan. Storing the resulting angles as LONG, and giving the input as LONG as well.

* At the moment my favorite, most work will be to find for which values(value-range) we will be calling atan and storing those results as LONGs. But if it would work out then we have a very fast way to calculate atan. If accuracy is low we could interpolate to improve it a little.

- Use an approximation for functions like atan. Ex:
x*(15+4*x*x)/(15+9*x*x);

* The given approximation still only works for radians, not getting us anywhere, but should be possible to create an approximation function where 1 rad = X. I have seen a post from 2006 on a newsgroup from someone who has implemented this - but his e-mail is hidden so I can't contact him.

- I've seen libraries that emulate the FPU registers. I am unsure how that would work or if I can even implement that in the kernel and it is probably slow, but that's based on random forum posts.

I would like to thank anyone in advance who is willing to elaborate about this with me.

- Trouble
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby L. Spiro » Sat Sep 12, 2009 8:33 am

I know Don Burns and his my-way-or-the-highway attitude.


I do not see a reason for the auto-aim to be entirely kernel (as apposed to doing the math in user-mode and using kernel for the interface), but I hate it when people question my own motives and tell me I don’t want to do what I want to do. Like when I rewrote the CRT and STL for my engine only to be met with, “Why reinvent the wheel?”.



Rather than hack through the FPU limitations, and in consideration of performance, it is best to simply use fixed-point math.

Make a fixed-point library (24.12 and 16.16 are the most common) and do a one-time buffer of the values in user-mode. This means collect all the values you need and convert them all at once in user-mode so you do not have to switch back and forth repeatedly.

At start-up, you can make cosine and sine tables from user-mode and upload them to the kernel.

There are also fixed-point functions available for cos(), sin(), and sqrt() available on the Internet.

Many mobile 3D games require at least the level of math needed for a correct auto-aim, and rely entirely on fixed-point math, so I can promise that there are fixed-point replacements for every function you need.




You will have to convert back to floating-point in user-mode before writing results to RAM, but the whole process involves only 2 switches between kernel-mode and user-mode and working with fixed-point values is faster than working with floating-point values, which allows you to get back all the time you lose during the switches and more.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby troublesh00ter » Sat Sep 12, 2009 1:05 pm

L. Spiro wrote:I know Don Burns and his my-way-or-the-highway attitude.

I do not see a reason for the auto-aim to be entirely kernel (as apposed to doing the math in user-mode and using kernel for the interface), but I hate it when people question my own motives and tell me I don’t want to do what I want to do. Like when I rewrote the CRT and STL for my engine only to be met with, “Why reinvent the wheel?”.


I've read many of you posts on driver-related forums and even though you do your homework and explain your problem in a clear, respectable way people are still reluctant to help when it is about something you "shouldn't be doing". But I am glad that this problem doesn't arise here.

The reason I'm doing it in kernel is because I've done it in user-mode. So I just want to see for myself if I can do it in kernel and learn as much as possible from it. I might be a little stubborn but I just want to see for myself how far I can come with just kernel-code, excluding some initializations. After all it's all for educational purposes, in production-code I'd do more in user-mode.

But you've convinced me that I am not wasting all of my time on this and will continue to dig into what you've said.

Thank you.

Trouble


Edit:

Make a fixed-point library (24.12 and 16.16 are the most common)

I guess you mean 24.8 here? If not then I'm missing something.
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby L. Spiro » Sat Sep 12, 2009 6:33 pm

20.12.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby troublesh00ter » Mon Sep 14, 2009 1:47 am

Alright, it is more-or-less doing what I intended at the moment, namely that it aims in the direction of the enemy with most of the code in kernel.

However as I'm starting to have fun doing this I've decided to actually make something useful that will also account for ping and other variables (much like the bot that you've written I guess). But I will be doing the calculations in user-mode.

So the current plan is:
- User-mode -> Kernel:
* Request needed values like positions, angles.

- User-mode:
* Do calculations.

- User-mode -> Kernel:
* Upload results from calculations and write to the RAM.

I was thinking of a way to avoid the first switch to kernel-mode, but I am not sure if it is worth spending time on:

We can have the kernel read the structures at a set interval and have it write these values to an allocated page in my user-mode application. When the kernel is done reading/writing it will fire an event in the user-mode signaling that the data is updated after which user-mode will use the values to perform the calculations and report back to kernel that it is done.

Will this have any significant effect? We lose the call to DeviceIoControl. But from what I know about DeviceIoControl it does approximately the same as what I described above, allocating a buffer where the input/output is written to.

--

On a completely different note, I was thinking about something that could help people bypass anti-cheat that hook KeStackAttachProcess. The AC I'm dealing with doesn't do this but still, it's an idea:

If we can initialize our driver before the AC hooks KeStackAttachProcess then we could create a system thread that attaches to the game, and after that waits infinitely for a KEVENT. Whenever we want to read something from the game, we save the addresses in a structure, fire the event and the system thread will read these addresses and store the results in a different structure.
Or is it really too dangerous to leave a thread attached for a long time?

Anyway it is not something I'd need directly, but if it's safe enough to do then it could save a call to Ke(un)Stack(de)AttachProcess every time we want to read something.

--

Trouble
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby troublesh00ter » Wed Sep 16, 2009 1:25 pm

No comments? Or am I asking a wrong question here.
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby L. Spiro » Wed Sep 16, 2009 3:40 pm

I was too busy to reply when I read it, and after that it no longer appeared as a new post.

There is no point in bypassing DeviceIoControl for this purpose.


I do not have the materials available now to research the feasibility of your second idea.
Ty it and see. There is nothing unsafe about leaving a thread running for any period of time.


I hope you have brushed up on your math if you plan to account for ping, bullet-time, inherited velocity, and predicting how the target will bounce off walls and the ground.

But then again the point of my up-coming tutorial is specifically to cover this math, so if you wait a while you will at least have a reference even if you do not figure it out on your own.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby troublesh00ter » Wed Sep 16, 2009 6:12 pm

No worries, I'm not in any rush.

I've implemented the thread that attaches to the process on start up and stays attached while waiting for an event to fire. I've not encountered any problems with this so far, but the documentation states that this could potentially deadlock. I guess it is safe as long as I keep the instructions in this routine simple.

I study mechanical engineering, which involves a lot of similar math, so I don't see a huge problem in this area.

Right now I'm working up a way to execute any in-game functions as I don't intend to inject any DLL in the target. So far it's coming up nicely...
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby troublesh00ter » Wed Sep 30, 2009 6:23 pm

Since my last post I've made a lot of progress, but I hit a brick wall that I've been trying to break down for over a week now.

The problem occurs in a function that is suppose to run a piece of code on every logical processor.

The basics of the function comes down to:
Code: Select all
VOID trRunFuncOnAllProcessors( )
{
    KAFFINITY           processors;
    PKTHREAD            thread;
    ULONG               i = 0;

    if( KeSetAffinityThread == NULL )
    {
        DbgPrint( "KeSetAffinityThread not initialized\n" );
        return;
    }

    processors         = KeQueryActiveProcessors();
    thread              = KeGetCurrentThread();

    for(i = 0; i < 32; i++) // @note: Only 32-bit for now
    {
        KAFFINITY curProc = processors & (1 << i);
        if ( curProc != 0 )
        {
            KeSetAffinityThread(thread, curProc);

            // Run some code here
        }
    }

    KeSetAffinityThread(thread, processors);
}


I use this function, for example, to hook the IDT (for now I wish to solve my problem by hooking the IDT, at a later stage I won't need this anymore but it just suits me now for development). The function never fails if I run it, for example, 'from' an IOCTL.

However, in my hooked interrupt (0Eh) I also call the function, and it bugchecks(IRQL_NOT_LESS_OR_EQUAL (a)) on KeSetAffinityThread.
During the week of trying to figure this out I used other functions in the hooked interrupt as well, like: KeSetEvent, KeWaitForSingleObject. So the problem isn't specific to this function.

They all bugcheck with the above message on: hal!KeAcquireQueuedSpinLock, more specifically:

Code: Select all
hal!KeAcquireQueuedSpinLock+0x27:
806e6a73 8b4a04          mov     ecx,dword ptr [edx+4] ds:0023:00000bd4=????????


An example of KeWaitForSingleObject that bugchecks:

Code: Select all

KeSetEvent( &gGPThreadArgs.kGPEvent, 0, FALSE );
KeWaitForSingleObject   ( &gGPThreadArgs.kGPEventDone, Executive, KernelMode, FALSE, &nWaitTime );


The events are initialized.

But this normally works if I run it, except not from the hooked interrupt.

At first I thought the interrupt handler is called at a raised IRQL, like the bugcheck suggests. But if I check the IRQL right before any of the above functions it is always PASSIVE_LEVEL.

Another thing worth noting: If I step through the code with WinDbg it runs fine. And that is where my imagination stops...

I hope you can provide some clarity to this.
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby L. Spiro » Wed Sep 30, 2009 7:12 pm

I am afraid only Don Burn can answer this question.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby troublesh00ter » Wed Sep 30, 2009 8:04 pm

Are you implying that this method is CRAP(no offense taken if you do) or you don't know either? ;)

I might as well implement the method that doesn't involve hooking the IDT, but that's some work that I didn't plan on doing yet.
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands

Postby L. Spiro » Wed Sep 30, 2009 8:36 pm

Only Don Burn and Chuck Norris know if this method is crap.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby troublesh00ter » Wed Sep 30, 2009 8:56 pm

Point taken, I'll go ahead to write it properly straight away... will have to anyway at some point.
troublesh00ter
Sir Hacks-A-Lot
 
Posts: 30
Joined: Mon Jun 01, 2009 2:54 pm
Location: The Netherlands


Return to Technical Unrelated

Who is online

Users browsing this forum: No registered users and 0 guests

cron