游戏的关键lua函数加了检测,主要是检测返回地址,而且不是检测返回地址是模块PE范围内就行,返回地址必须是游戏真实调用lua函数的返回地址,而且检测字节码...
例子:
还是看代码:
告诉大家,wow 从调试到注入到调用lua,不需要任何r0技术,不要再用高射炮打蚊子了......
这是2020年1.13.6.36714 作为例子写的,理解了原理套用现在的版本就没问题
WOW 使用了PE节保护技术,重新映射PE内存,致使PE节不可修改,这个技术比较有意思,可以参考 [
self
-
remapping](https:
/
/
github.com
/
changeofpace
/
Self
-
Remapping
-
Code)
WOW 使用了PE节保护技术,重新映射PE内存,致使PE节不可修改,这个技术比较有意思,可以参考 [
self
-
remapping](https:
/
/
github.com
/
changeofpace
/
Self
-
Remapping
-
Code)
只喜欢用lua凑合看吧,都是调用windowsapi领会意思就行
注意先SuspendProcess,重新映射后ResumeProcess
只喜欢用lua凑合看吧,都是调用windowsapi领会意思就行
注意先SuspendProcess,重新映射后ResumeProcess
local STATUS_SUCCESS
=
0
local ViewShare
=
1
local ViewUnmap
=
2
local SEC_NO_CHANGE
=
0x00400000
;
local SEC_COMMIT
=
0x08000000
local MEM_RELEASE
=
0x00008000
local NULL
=
ffi.cast(
"void *"
,
0
)
function _RemapViewOfSection(ProcessHandle, BaseAddress, RegionSize, NewProtection, CopyBuffer)
local numberOfBytesRead
=
ffi.new(
"SIZE_T[1]"
)
if
ffi.C.ReadProcessMemory(ProcessHandle, ffi.cast(
"void *"
, BaseAddress), ffi.cast(
"void *"
, CopyBuffer), RegionSize, numberOfBytesRead)
=
=
0
then
return
false;
end
local hSection
=
ffi.new(
"HANDLE[1]"
);
local sectionMaxSize
=
ffi.new(
"LARGE_INTEGER[1]"
)
sectionMaxSize[
0
].QuadPart
=
RegionSize;
local status
=
win.ntdll.NtCreateSection(hSection, win.SECTION_ALL_ACCESS, NULL, sectionMaxSize, win.PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
if
(status ~
=
STATUS_SUCCESS) then
return
false;
end
-
-
/
/
Unmap the current view.
status
=
win.ntdll.NtUnmapViewOfSection(ProcessHandle, ffi.cast(
"void *"
, BaseAddress));
if
status ~
=
STATUS_SUCCESS then
return
false;
end
local viewBase
=
ffi.new(
"uintptr_t[1]"
, BaseAddress)
local sectionOffset
=
ffi.new(
"LARGE_INTEGER[1]"
)
local viewSize
=
ffi.new(
"SIZE_T[1]"
);
status
=
win.ntdll.NtMapViewOfSection(
hSection[
0
],
ProcessHandle,
ffi.cast(
"void **"
, viewBase),
0
,
RegionSize,
sectionOffset,
viewSize,
ViewUnmap,
0
,
NewProtection);
if
status ~
=
STATUS_SUCCESS then
return
false;
end
local numberOfBytesWritten
=
ffi.new(
"SIZE_T[1]"
)
if
ffi.C.WriteProcessMemory(ProcessHandle, ffi.cast(
"void *"
, viewBase[
0
]), ffi.cast(
"void *"
, CopyBuffer), viewSize[
0
], numberOfBytesWritten)
=
=
0
then
return
false;
end
return
true;
end
function RemapViewOfSection(ProcessHandle, BaseAddress, RegionSize, NewProtection)
local copybuf
=
ffi.C.VirtualAlloc(ffi.cast(
"void *"
,
0
), RegionSize, bit.bor(win.MEM_COMMIT, win.MEM_RESERVE), win.PAGE_EXECUTE_READWRITE)
if
not
copybuf then
return
false
end
local result
=
_RemapViewOfSection(ProcessHandle, BaseAddress, RegionSize, NewProtection, copybuf);
ffi.C.VirtualFree(copybuf,
0
, MEM_RELEASE);
return
result;
end
local PROCESS_ALL_ACCESS
=
0x1fffff
local BaseAddress
=
0x0000000140000000
local RegionSize
=
0x0000000002330000
local NewProtection
=
0x40
local 进程名
=
"wowclassic.exe"
local tbl
=
enum.EnumSystemProcessorInformation()
for
_, process
in
pairs(tbl) do
local processname
=
process.Name:lower()
if
processname
=
=
进程名 then
local hProcess
=
ffi.C.OpenProcess(PROCESS_ALL_ACCESS,
0
, process.Pid);
if
hProcess then
win.ntdll.NtSuspendProcess(hProcess)
print
(RemapViewOfSection(hProcess, BaseAddress, RegionSize, NewProtection))
win.ntdll.NtResumeProcess(hProcess)
ffi.C.CloseHandle(hProcess)
break
end
end
end
local STATUS_SUCCESS
=
0
local ViewShare
=
1
local ViewUnmap
=
2
local SEC_NO_CHANGE
=
0x00400000
;
local SEC_COMMIT
=
0x08000000
local MEM_RELEASE
=
0x00008000
local NULL
=
ffi.cast(
"void *"
,
0
)
function _RemapViewOfSection(ProcessHandle, BaseAddress, RegionSize, NewProtection, CopyBuffer)
local numberOfBytesRead
=
ffi.new(
"SIZE_T[1]"
)
if
ffi.C.ReadProcessMemory(ProcessHandle, ffi.cast(
"void *"
, BaseAddress), ffi.cast(
"void *"
, CopyBuffer), RegionSize, numberOfBytesRead)
=
=
0
then
return
false;
end
local hSection
=
ffi.new(
"HANDLE[1]"
);
local sectionMaxSize
=
ffi.new(
"LARGE_INTEGER[1]"
)
sectionMaxSize[
0
].QuadPart
=
RegionSize;
local status
=
win.ntdll.NtCreateSection(hSection, win.SECTION_ALL_ACCESS, NULL, sectionMaxSize, win.PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
if
(status ~
=
STATUS_SUCCESS) then
return
false;
end
-
-
/
/
Unmap the current view.
status
=
win.ntdll.NtUnmapViewOfSection(ProcessHandle, ffi.cast(
"void *"
, BaseAddress));
if
status ~
=
STATUS_SUCCESS then
return
false;
end
local viewBase
=
ffi.new(
"uintptr_t[1]"
, BaseAddress)
local sectionOffset
=
ffi.new(
"LARGE_INTEGER[1]"
)
local viewSize
=
ffi.new(
"SIZE_T[1]"
);
status
=
win.ntdll.NtMapViewOfSection(
hSection[
0
],
ProcessHandle,
ffi.cast(
"void **"
, viewBase),
0
,
RegionSize,
sectionOffset,
viewSize,
ViewUnmap,
0
,
NewProtection);
if
status ~
=
STATUS_SUCCESS then
return
false;
end
local numberOfBytesWritten
=
ffi.new(
"SIZE_T[1]"
)
if
ffi.C.WriteProcessMemory(ProcessHandle, ffi.cast(
"void *"
, viewBase[
0
]), ffi.cast(
"void *"
, CopyBuffer), viewSize[
0
], numberOfBytesWritten)
=
=
0
then
return
false;
end
return
true;
end
function RemapViewOfSection(ProcessHandle, BaseAddress, RegionSize, NewProtection)
local copybuf
=
ffi.C.VirtualAlloc(ffi.cast(
"void *"
,
0
), RegionSize, bit.bor(win.MEM_COMMIT, win.MEM_RESERVE), win.PAGE_EXECUTE_READWRITE)
if
not
copybuf then
return
false
end
local result
=
_RemapViewOfSection(ProcessHandle, BaseAddress, RegionSize, NewProtection, copybuf);
ffi.C.VirtualFree(copybuf,
0
, MEM_RELEASE);
return
result;
end
local PROCESS_ALL_ACCESS
=
0x1fffff
local BaseAddress
=
0x0000000140000000
local RegionSize
=
0x0000000002330000
local NewProtection
=
0x40
local 进程名
=
"wowclassic.exe"
local tbl
=
enum.EnumSystemProcessorInformation()
for
_, process
in
pairs(tbl) do
local processname
=
process.Name:lower()
if
processname
=
=
进程名 then
local hProcess
=
ffi.C.OpenProcess(PROCESS_ALL_ACCESS,
0
, process.Pid);
if
hProcess then
win.ntdll.NtSuspendProcess(hProcess)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)