Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


THREADSTACK0 does not appear as a module. C#

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
UzuStark98
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 6
Location: here

PostPosted: Sat Jul 04, 2015 4:06 pm    Post subject: THREADSTACK0 does not appear as a module. C# Reply with quote

Hello,

I am creating a simple C# utility application that helps the user by reading the memory and then doing something depending on the value read. I am trying to read an address in memory but the only viable pointer that is left in the pointer scan window is from the module "THREADSTACK0". When I tried to implement it in my c# app, it gave me the wrong address so I used this

Code:
foreach (ProcessModule Module in ygo.Modules)
            {
                MessageBox.Show(Module.ModuleName);
                if (Module.ModuleName.Contains("THREADSTACK0"))
                    BaseAddress = Module.BaseAddress;
            }


and it showed some modules but none of them was called "THREADSTACK0"

Anybody has any idea how I could deal with this? I googled around but I couldnt find anything to help.

Edit: So, apparently its not a module..... I tried getting all the threads and using NtQueryInformationThread on them to find their base address and I added THREADSTACK0 in CE as an address but none of the threads match with the one that showed in CE....
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 157

Joined: 25 Jan 2006
Posts: 8102
Location: 127.0.0.1

PostPosted: Sat Jul 04, 2015 10:11 pm    Post subject: Reply with quote

See here for more info on what THREADSTACK0 means:
http://forum.cheatengine.org/viewtopic.php?p=5487976#5487976

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
UzuStark98
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 6
Location: here

PostPosted: Sun Jul 05, 2015 8:23 am    Post subject: Reply with quote

I saw that and did what he said except for the last part about scanning for a Direct or Indirect reference to ExitThread because I really have no idea how to do that and google isnt helping..... I already added to my answer that I searched for the threads using NtQueryInformationThread.
Back to top
View user's profile Send private message
STN
I post too much
Reputation: 36

Joined: 09 Nov 2005
Posts: 2588

PostPosted: Sun Jul 05, 2015 11:28 am    Post subject: Reply with quote

UzuStark98 wrote:
I saw that and did what he said except for the last part about scanning for a Direct or Indirect reference to ExitThread because I really have no idea how to do that and google isnt helping..... I already added to my answer that I searched for the threads using NtQueryInformationThread.


I am not sure if DB means ExitThread should be scanned from within your program or manually using CE/Debuggers. If its the latter, you can use this great program called API Monitor (used to frequent that place in past)
http://www.rohitab.com/apimonitor#Download

If he means the former, download the source code of FileMon (API hooker) or google for API hooking source code and there should be sources/tutorials on how to do that. I vaguely remember someone from gamehacking field wrote something similar to API hooking years ago, can't remember who so Google and you may find it.

Alternatively, you can enumerate all the threads in a listbox or wherever and notice what your thread is actually called ?.


PS: I quickly skimmed through your topic and the linked one so apologies if it isn't what you want.

_________________
Cheat Requests/Tables- Fearless Cheat Engine
https://fearlessrevolution.com
Back to top
View user's profile Send private message
UzuStark98
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 6
Location: here

PostPosted: Mon Jul 06, 2015 10:46 am    Post subject: Reply with quote

Thank you for your reply!

Should I use the API monitor to monitor ExitThread or do you mean use it to check the threads? Well, the api monitor doesn't detect any ExitThread in the app I am trying to read and about reading the Thread Start Addresses.... That's the thing, none of them match the one in CE, even when I looped through the threads in the Process(which I had already done before, it's in my post Wink ) still none of them matched the one in CE and they didn't reach the correct address that I get from using the address in CE....

How do I know where exactly does that THREADSTACK0 start?

EDIT: Also, I just have to say this but your signature is just simply hilarious Laughing
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 384

Joined: 09 May 2003
Posts: 23106
Location: The netherlands

PostPosted: Mon Jul 06, 2015 12:12 pm    Post subject: Reply with quote

What you're looking for is the first value on the stack of the first thread from the point the thread is initialized and starts running.

This is often a pointer to a thread termination function, or behind a thread initialization call.
E.g in windows 7 it's after the call inside BaseThreadInitThunk

Easiest is just look for a reference inside kernel32 (not ntdll) and use that as a starting point

Here is the sourcecode on how cheat engine does it:
https://github.com/cheat-engine/cheat-engine/blob/master/Cheat%20Engine/CEFuncProc.pas#L3093

and yes, I am quite aware this is a nightmare to look at when you're used to c# doing everything for you

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
STN
I post too much
Reputation: 36

Joined: 09 Nov 2005
Posts: 2588

PostPosted: Mon Jul 06, 2015 12:36 pm    Post subject: Reply with quote

Hey UzuStark98, I meant checking the API within threads. However, scratch that. CE source has the answer.

Quote:
//find the stack entry pointing to the function that calls "ExitXXXXXThread"
//Fun thing to note: It's the first entry that points to a address in kernel32

getmem(buf,4096);

if ReadProcessMemory(processhandle, pointer(stacktop-4096), buf, 4096, x) then
begin
if processhandler.is64Bit then
begin
for i:=(4096 div Cool-1 downto 0 do
if inrangeq(buf64[i], mi.baseaddress, mi.baseaddress+mi.basesize) then
begin
result:=stacktop-4096+i*8;
break;
end;
end
else
begin
for i:=(4096 div 4)-1 downto 0 do
if inrangeq(buf32[i], mi.baseaddress, mi.baseaddress+mi.basesize) then
begin
result:=stacktop-4096+i*4;
break;
end;


In the CEFuncProc (https://github.com/cheat-engine/cheat-engine/blob/master/Cheat%20Engine/CEFuncProc.pas#L3093), line 3093 is the start of the function. Just browse around in CE Source, interesting stuff in there Very Happy

_________________
Cheat Requests/Tables- Fearless Cheat Engine
https://fearlessrevolution.com
Back to top
View user's profile Send private message
UzuStark98
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 6
Location: here

PostPosted: Mon Jul 06, 2015 2:01 pm    Post subject: Reply with quote

Thank you both so much for your help!

I will dig through the source code(even though I don't understand most of it) and try to figure out how to go about it.

Again, thank you for your help!
Back to top
View user's profile Send private message
UzuStark98
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 6
Location: here

PostPosted: Tue Jul 07, 2015 8:12 am    Post subject: Reply with quote

Hi, I know I am being a bother but please bear with me...

After a full day of headaches and suicidal attempts, I have almost ported that function you gave me the link to, to c#. But, I am having a few problems...

I imported the GetThreadContext from kernel32.dll in this form:

Code:
[DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext);


and I made the CONTEXT struct like the documentation said and then tried to use it but the code runs perfectly it keeps looping through the threads using Thread32First and Thread32Next till it finds a thread that my process owns and then I create a CONTEXT c and then set its ContextFlags to CONTEXT_SEGMENT and then call the GetThreadContext but it always fails and sets LastError to Error 5.

I even tried Wow64GetThreadContext and got the same error.

One more thing....

Code:
//get the first thread of this process
  if symhandler.getmodulebyname('kernel32.dll', mi)=false then
  begin
    symhandler.loadmodulelist;
    if symhandler.getmodulebyname('kernel32.dll', mi)=false then
      exit;
  end;


Right before you call the symhandler.getmodulebyname you say that it gets the first thread of this process? I don't understand how getting the kernel32.dll module gets a thread and it gets placed in mi which is not used till later on in the function.

Again, I know I am being a bother but please understand that I had never even saw a Delphi source before so from jumping from 0 to (OVER 9000), I think I did pretty well with the code? XD

well anyways here is the part about getting the threads and then getting their context:

Code:
Process proc = Process.GetProcessesByName("proc_name")[0];
            procHandle = Functions.ProcessOpen(ygo); //Returns the handle of the process

           procBase = proc.MainModule.BaseAddress; //Getting the BaseAddress of the MainModule just incase we need it

            IntPtr snapshothandle = Functions.CreateToolhelp32Snapshot(Functions.SnapshotFlags.Thread, 0); //Creating the snapshot of the current Threads
            if (snapshothandle != new IntPtr(-1)) //Checking if its invalid
            {
                Functions.THREADENTRY32 te32 = new Functions.THREADENTRY32(); //Initializing the THREADENTRY32
                te32.dwSize = (uint)sizeof(Functions.THREADENTRY32); //Setting its dwsize to that of THREADENTRY32

                if (Functions.Thread32First(snapshothandle, ref te32)) //I know it will skip the first thread with this method but my brain was overloading so I just made whatever came to mind :D
                {
                    while (Functions.Thread32Next(snapshothandle, out te32)) // but it wont matter because the first thread is always 0 in everything
                    {
                        if (te32.th32OwnerProcessID == proc.Id) //check if its our proc's thread
                        {
                            IntPtr threadhandle = Functions.GetThreadHandle((int)te32.th32ThreadID); //Get the thread's handle

                            /*var hThread = OpenThread(ThreadAccess.QueryInformation, true, threadId);
            if (hThread == IntPtr.Zero)
                throw new Exception();
            return hThread;*/ //Using that if you were wondering....

                            byte[] buffer = new byte[8];
                            int read = 0;

                            IntPtr stacktop = new IntPtr();

                            buffer = new byte[4096];

                                Functions.CONTEXT c = new Functions.CONTEXT();
                                c.ContextFlags = (UInt32)Functions.CONTEXT_FLAGS.CONTEXT_SEGMENTS;

                                if (Functions.GetThreadContext(threadhandle, ref c))
                                {
                                    MessageBox.Show("Correct Thread Context"); //Never reaches this part

                                    Functions.LDT_ENTRY ldtentry = new Functions.LDT_ENTRY();

                                    if (Functions.GetThreadSelectorEntry(threadhandle, c.SegFs, out ldtentry))
                                    {
                                        Functions.ReadProcessMemory(Network.YgoHandle.ToInt32(), new IntPtr(ldtentry.BaseLow + ldtentry.HighWord.Bytes.BaseMid << 16 + ldtentry.HighWord.Bytes.BaseHi << 24) + 4, buffer, 4, ref read);
                                        stacktop = new IntPtr(BitConverter.ToInt32(buffer, 0));
                                    }
                                }
                                else
                                {
                                    MessageBox.Show(Marshal.GetLastWin32Error().ToString());
                                }
                            }

                            Functions.CloseThreadHandle(threadhandle);
                       }
                  }
             }
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 384

Joined: 09 May 2003
Posts: 23106
Location: The netherlands

PostPosted: Tue Jul 07, 2015 10:51 am    Post subject: Reply with quote

GetThreadContext also needs TREAD_GET_CONTEXT besides THREAD_QUERY_INFORMATION
are you sure the address of Context is alligned on a 128-bit alignment?
Did you implement Context yourself? Is your application set to run in 64 or 32 bit? or default? (i think default means windows randomly picks 32 or 64 bit just to annoy you)


getModuleByName fills the mi (moduleinfo) structure with information about it like base and size. It's a result of module32first/next

the range of kernel32 is used to compare against the values in the stack of the thread

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
UzuStark98
How do I cheat?
Reputation: 0

Joined: 04 Jul 2015
Posts: 6
Location: here

PostPosted: Wed Jul 08, 2015 9:47 am    Post subject: Reply with quote

Dark Byte wrote:
GetThreadContext also needs TREAD_GET_CONTEXT besides THREAD_QUERY_INFORMATION
are you sure the address of Context is alligned on a 128-bit alignment?
Did you implement Context yourself? Is your application set to run in 64 or 32 bit? or default? (i think default means windows randomly picks 32 or 64 bit just to annoy you)


getModuleByName fills the mi (moduleinfo) structure with information about it like base and size. It's a result of module32first/next

the range of kernel32 is used to compare against the values in the stack of the thread


Ok, I thought I was giving it THREAD_GET_CONTEXT but I wasn't Very Happy .... No, I didn't implement it myself I followed the documentation but I didn't really understand because all this is soooo undocumented. I found out that my application is set to launch in 64-bit so I used the method in your CE code which targeted 64-bit but it reaches the end with a wrong address and it can't read the last memory address so it returns 0.

In the end, this was just a side project that I took as a learning process but this is taking alot of time from me I have been working non-stop on it for the past week and I stopped working on my actual projects XD . So, I will just have to give up for now.

Thank you very much for your help!
Back to top
View user's profile Send private message
MakeMEK
How do I cheat?
Reputation: 0

Joined: 28 Dec 2015
Posts: 2

PostPosted: Mon Dec 28, 2015 10:50 am    Post subject: Reply with quote

After four sleepless nights and tons of googling, I finally manage to get THREADSTACK address in c++. I will share my solution Smile.

THREADSTACK is not a DLL module. That's why you can't load the module.
It is a process's thread.
One process can have multiple threads.
When the process starts, it requests threads from the operating system (kernel32 for Windows, POSIX for Linux).
Kernel32 (kernel32.dll) and POSIX (pthread.so) are libraries that manage thread execution and scheduling.

I am going to focus on Windows because most games are developed in Windows platform.
Each thread's memory segment from top-down consists of stack, heap, data, and text.

Stack keeps function's caller address located at the top-most thread's memory segment. It grows top-down. The stack limit size is 4096 bytes (32-bit), 8192 bytes (64-bit).
Heap is a dynamic memory allocated at runtime. It grows bottom-up.
Data section contains global and static variables.
Text section is a program's instructions located at the bottom-most thread's memory segment.


A first thread (Lowest TID) is the main thread provided by the kernel to execute main().
Other threads are written by developer to achieve concurrent execution.
Cheat engine associates THREADSTACK with each thread starting from 0.
THREADSTACK0 associates with the main thread.
THREADSTACK1 ... THREADSTACK# associates with other threads created by the developer.

You can view exact THREADSTACK address by going to memory view -> right click -> Go to address -> type THREADSTACK# where # is an integer.

Cheat engine use the word THREADSTACK to refer to ExitThread() function address.
THREADSTACK address is not static because the process creates it at run time.
However, it doesn't mean we can't find it.
Remember that when process starts, it requests a kernel thread.
Meaning that, all process use kernel32.dll to get a thread and execute its code.
Inside kernel32.dll, there is a function called ExitThread() used to terminate a thread.
Every threads in every processes must call ExitThread() to terminate itself at the end of execution.
Thus, we can use ExitThread() function address as a static starting point.
Cheat engine usually includes -OFFSETS after THREADSTACK# to go up in stack memory segment to the function caller.
Then, it deferences the function call address leading to the program's code section and move on from there.

In my opinion, cheat engine use THREADSTACK as a last way to get to the variable.
They are usually in game that have multiple threads sharing the same variable.
The variable that you are looking for is shared to multiple threads.
It is likely that there are static pointers from different threads pointing to the same variable.
But those static pointers reside within the thread itself not global.
Cheat engine can't display the exact address because it needs to know which thread owns that static pointer.

When you do pointer scan, you will get THREADSTACK0 or THREADSTACK1 most of the time.
When you writing code for a multi-threaded program, each thread should run independently.
If you need to share data among other threads, you should create shared data in the main thread and let other threads read/write the data.
Otherwise, they will be very hard to maintain.
We can't read/write data properly because we don't know when the thread going to be created and terminated.
But we know for sure that main thread starts when we run the program and terminate when we exit the program.
That's why most of the shared variables resides in the main thread.

How do we find it?
1. Get all TIDs associate with your application (PID).
Using CreateToolhelp32Snapshot() to iterate all PIDs and TIDs.
Find your target PID then get all its TIDs.

2. Get your TID of interest.
What THREADSTACK number that you are looking for?.
The output of CreateToolhelp32Snapshot() has TIDs ascending sorted.
THREADSTACK number is the TID's index element.

3. Find Thread's stack base address.
We need to know where thread's memory segment starts.
The top-most thread memory segment is the stack.
We have to look for stack base address.
To get it, you have call NtQueryInformationThread() from ntdll.dll.

4. Find the stack entry pointing to the function that calls "ExitThread()"
We know where stack memory segment starts.
We also know that Windows allocates stack size 4096 bytes for 32-bit app and 8192 bytes for 64-bit app.
We can create a buffer to read stack addresses.
Then, we iterate all addresses inside stack memory section comparing each address to see whether it exists inside kernel32.dll.
If we find it, which is always the case, we found address call to ExitThread() function.
We will use this as a base address and perform offset calculation that you get from cheat engine as usual.

Here is the code implement in C++.
Some function I have to rewrite cheat engine's source code (Delphi) in C++. Quite a headache Shocked
Please note that the solution only works for 32-bit Windows process only.
I haven't done 64-bit process yet.
I can't post image or provide url link at the moment because I've just registered to the forum Razz.

The code is on my github.
Total codes are around 300 lines long. I can't post them here.
githubDOTcom/makemek/cheatengine-threadstack-finder
(replace DOT with .)

You have to parse PID in decimal as a command line argument.
If you want to use with your trainer, I recommend to get process's handle by window name (FindWindow() and GetProcessWindowThreadProcessId() functions).
So you don't have to input PID everytime. Let the program find it automatically.
After you get thread stack base address, calculate pointer offset that you get from cheat engine as usual.

I also create a DLL library to encapsulate implementation details.
They are in another branch (dll-export).
Just call baseThreadstackAddress() passing PID and stack number as parameters.
It will return an address to THREADSTACK.

I don't know how write them in C#, but C++ and C# are similar.
I'm sure you can convert it Smile.

After I got this, I jump around full of joy.
It is so damn hard, yet so satisfying Very Happy.

RESULT
[img]s9.postimg.org/wiqi8d9kv/cheatengine_result.png[/img]


FYI
When I list all process's TIDs, it results in the same number of total threadstacks.
Cheat engine can't find the address when I input number that is larger than total TIDs.
For example, if a process has 5 threads, there will be 5 threadstacks available.

For more details about kernel and thread, I recommend reading Operating System Concepts 9th edition by Abraham Silberschatz chapter 4.
Back to top
View user's profile Send private message
CausalGamer
How do I cheat?
Reputation: 0

Joined: 22 Apr 2010
Posts: 4

PostPosted: Sat Oct 05, 2019 7:00 am    Post subject: Reply with quote

I know this is a age old thread but it did help me a lot with my issue.
As a reslut I created a video trying my best to explain how to work with threadstack pointers.

That beein said. Most of the information provided can already be found in this thread right here so if you prefer reading there is no need to watch it Wink

Thanks a lot to the amazing ppl in this thread doing a gread job spreading their knoledge <3

Type "Cheat Engine THREADSTACK Pointers in C++ | Memory Hacking" in youtube search bar if you still want to check it out
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 157

Joined: 25 Jan 2006
Posts: 8102
Location: 127.0.0.1

PostPosted: Sun Oct 06, 2019 12:50 pm    Post subject: Reply with quote

Here's a link to CasualGamer's vid since he can't post links yet:
https://www.youtube.com/watch?v=YDHE42QIRNQ

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites