Cheat Engine 修改器获取内存数据心路历程, THREADSTACK0 C# .NET VB 获取基址 CE修改器

一、CE 找到地址

根据字符串找到地址。
在这里插入图片描述

在这里插入图片描述
找到结果,双击此行,会加入下面列表
在这里插入图片描述
右键点击选择:对这个地址进行指针扫描。
在这里插入图片描述
此处选择10级别指针,其他程序 区别对待。

参考此教程:
CE学习资料

在这里插入图片描述
经过多次查找可以找到如下结果
在这里插入图片描述
平常程序的 基址 都是以.exe或者 .dll 结尾,这里是 THREADSTACK0,表示是 线程0基地址。

二、获取THREADSTACK0 基址

获取基址:
C++项目程序
threadstack.exe 软件
在这里插入图片描述

三、修改C++代码,生成dll,使用的是VS2019 。

增加一个方法,作用是传入一个程序的 PID,和线程序号,程序返回线程的基址(10进制)。

int GetThreadStartAddress_SSY(int Pid, int intThreadNo) {
	std::string pid = std::to_string(Pid);
	DWORD dwProcID;
	std::stringstream stringstream(pid);
	stringstream >> std::dec >> dwProcID;
	if (!dwProcID) {
		std::cerr << pid << " is not a valid process id (PID)" << std::endl;
		return 0;
	}
	HANDLE hProcHandle = NULL;
	hProcHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcID);
	std::vector<DWORD> threadId = threadList(dwProcID);
	int stackNum = 0;
	for (auto it = threadId.begin(); it != threadId.end(); ++it) {
		if (stackNum == intThreadNo)
		{
			HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, *it);
			DWORD threadStartAddress = GetThreadStartAddress(hProcHandle, threadHandle);
			printf("TID: 0x%04x = THREADSTACK%2d BASE ADDRESS: 0x%04x\n", *it, stackNum, threadStartAddress);
			return threadStartAddress;
		}
		stackNum++;
	}
	return 0;
}

添加可被调用函数:

extern "C" FUNHEAD int  GetThreadStartAddress_SSY(int Pid, int intThreadNo);

在这里插入图片描述

修改项目为:动态库(.dll) ,点击F5生成,得到threadstack.dll。
在这里插入图片描述

三、VB.NET程序示范

1.获取线程基址
把 threadstack.dll 放入程序运行目录下。
dll下载地址
我会上传到优快云,付积分下载(有钱真的可以为所欲为哦),当然也可以按照我的方法编译。

    <DllImport("threadstack.dll", CharSet:=CharSet.Unicode, SetLastError:=True, CallingConvention:=CallingConvention.Cdecl)>
    Private Shared Function GetThreadStartAddress_SSY(ByVal hProcess As ULong, ByVal hThread As ULong) As Integer
    End Function
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        m_csTargetProcess = Process.GetProcesses().FirstOrDefault(Function(k) k.ProcessName = txt_ExeName.Text)
        If m_csTargetProcess Is Nothing Then
            MsgBox("未检索到程序!")
            Return
        End If
        Dim csBaseAddress As System.IntPtr = IntPtr.Zero '线程的基址
        csBaseAddress = GetThreadStartAddress_SSY(m_csTargetProcess.Id, 0)
   
   '下面还有代码

在这里插入图片描述
2.根据基址+偏移获取最终地址。
在这里插入图片描述

'此代码接上面的
'获取最终地址
 csBaseAddress = csBaseAddress - &H384 '基址
 Dim hProcess As IntPtr = OpenProcess(&H1F0FFF, False, m_csTargetProcess.Id) '主窗体句柄
 csBaseAddress = hProcess.FindDMAAddy(csBaseAddress, New Integer() {&H28, &H4, &H8, &H120, &H10, &H14, &HC4, &H10, &H8, &H10})

 Dim Size As Integer = 20 '请求多少数据
        Dim array As Byte() = New Byte(Size - 1) {}
        Dim num As Integer '响应多少个数据
        ReadProcessMemory(hProcess, csBaseAddress, array, Size, num)
        Dim strTarge As String = System.Text.UnicodeEncoding.Unicode.GetString(array)
        MsgBox(strTarge)
        CloseHandle(hProcess)

    End Sub 

<DllImportAttribute("kernel32.dll", EntryPoint:="ReadProcessMemory")>
    Public Function ReadProcessMemory(hProcess As IntPtr,
                                             lpBaseAddress As IntPtr,
                                             <Out()> lpBuffer As Byte(),
                                             dwSize As Integer,
                                             <System.Runtime.InteropServices.OutAttribute()>
                                             ByRef lpNumberOfBytesRead As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <System.Runtime.CompilerServices.Extension>
    Public Function FindDMAAddy(ByVal hProc As IntPtr, ByVal ptr As IntPtr, ByVal offsets() As Integer) As IntPtr
        Dim buffer = New Byte(IntPtr.Size - 1) {}
        For Each i As Integer In offsets
            ReadProcessMemory(hProc, ptr, buffer, buffer.Length, 0)
            If IntPtr.Size = 4 Then
                ptr = IntPtr.Add(New IntPtr(BitConverter.ToInt32(buffer, 0)), i)
            Else
                ptr = IntPtr.Add(New IntPtr(BitConverter.ToInt64(buffer, 0)), i)
            End If
        Next i
        Return ptr
    End Function

四、总结

第一次使用CE写项目,熬了几个大夜终于搞定了。我们遇到的问题刚好在我们的能力范围内,或许再坚持一下,我们就能把问题解决了。
瑞思拜。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值