Vape (Vape Ghost Client) 是一个 Minecraft 作弊客户端。Vape 客户端允许玩家在 Minecraft 中使用一些自动化功能或作弊工具,如自动瞄准、飞行、透视等。该客户端使用特殊的加载方式(动态注入)在 Windows 平台下比较受欢迎,本文章通过逆向工程,分析VapeV4与VapeLite,阐述该客户端的工作原理。
注:本程序分析截至 2025/07/15,不保证后续更新版本是否会对核心功能进行修改。
分析 VapeV4
主程序
一般情况下,主程序是从官网下载的,名字是 f"{random_hex_str}.exe" ,部分代码使用CodeVirtualizer进行代码虚拟化。
main函数
main函数仅输出1,而后进入after_main
我们认为 after_main 函数也是main函数的一部分。
申请 SeDebugPrivilege 权限
因为主程序要使用 OpenProcess API操作其他程序,且要执行远程线程注入,申请此权限是必须的。
socket 监听本地地址
bind_localhost函数监听本地地址(127.0.0.1),用于和注入的客户端进行通信。
RenderingUI
RenderingUI启用了两个线程,并且有一个循环负责同步。
第一个线程用于渲染Login界面,第二个线程用于与第一个线程配合,完成App-Auth流程。
在UI渲染完毕后,该函数返回。
Vape客户端的UI渲染通过一个循环实现,使用了大量的OpenGL API,笔者对于GL不熟悉,技术细节在此不表。
不过显而易见的,各种界面的切换是通过一个全局变量决定的。
检测 Minecraft 存活
通过进程名检测
_BOOL8 __fastcall checkValidMinecraftProcess(PROCESSENTRY32W *a1)
{
return wcsstr(a1->szExeFile, L"javaw.exe") || wcsstr(a1->szExeFile, L"java.exe") || wcsstr(a1->szExeFile, L"Paladium");
}
bool __fastcall locateProcess(_QWORD *a1)
{
CHAR *v2; // rax
signed __int64 v3; // rcx
unsigned __int8 v4; // dl
int v5; // eax
unsigned __int8 *ProcessParameters; // [rsp+20h] [rbp-788h]
HWND hWnd; // [rsp+30h] [rbp-778h]
HANDLE hSnapshot; // [rsp+40h] [rbp-768h]
PROCESSENTRY32W pe; // [rsp+50h] [rbp-758h] BYREF
CHAR ClassName[256]; // [rsp+290h] [rbp-518h] BYREF
CHAR String[1024]; // [rsp+390h] [rbp-418h] BYREF
hSnapshot = CreateToolhelp32Snapshot(2u, 0);
pe.dwSize = 568;
if ( !Process32FirstW(hSnapshot, &pe) )
return 0;
do
{
if ( checkValidMinecraftProcess(&pe) )
{
ProcessParameters = getProcessParameters(pe.th32ProcessID);
hWnd = (HWND)sub_14004BD10(pe.th32ProcessID);
if ( hWnd )
{
if ( ProcessParameters && _strstr((const char *)ProcessParameters, "MojangTricksIntelDriversForPerformance") )
goto LABEL_18;
memset(String, 0, sizeof(String));
GetWindowTextA(hWnd, String, 1024);
if ( _strstr(String, "Minecraft 1.")
|| _strstr(String, "????")
|| _strstr(String, "Paladium")
|| _strstr(String, " Client") )
{
goto LABEL_18;
}
memset(ClassName, 0, sizeof(ClassName));
GetClassNameA(hWnd, ClassName, 256);
v2 = ClassName;
v3 = "LWJGL" - ClassName;
while ( 1 )
{
v4 = *v2;
if ( *v2 != v2[v3] )
break;
++v2;
if ( !v4 )
{
v5 = 0;
goto LABEL_17;
}
}
v5 = v4 < (unsigned __int8)v2[v3] ? -1 : 1;
LABEL_17:
if ( !v5 )
LABEL_18:
sub_14004C2B0(a1, &pe.th32ProcessID);
}
if ( ProcessParameters )
j_j_free(ProcessParameters);
}
}
while ( Process32NextW(hSnapshot, &pe) );
return !sub_14001F750(a1);
}
在检测到指定的程序名后,Vape会检测其标题名是否合法,若合法,还会检查窗口类名是否为"LWJGL",进一步提高目标进程的准确性,若未找到Minecraft,Vape会进行循环一直寻找,直到查找到,然后会在GUI上显示,让用户选择。
对于已注入的客户端,Vape会进行检测。
Vape主程序会尝试创建一个pipe,名称后面加上pid,若创建成功,则证明客户端已被注入,若创建失败且上一次的错误是0xE7(ERROR_PIPE_BUSY),说明客户端已被注入,否则证明客户端未被注入。
这也是一种检测Vape客户端的方案,检测工具只需检测此通道的有效性即可证明是否注入Vape客户端。
当然,最简单且有效的方案其实是对java.exe的内存进行全量扫描。
Hwid
Vape 采用硬盘序列号来生成Hwid,在我这里,Hwid是长度为8的hex字符串。
Login
RenderingUI完毕后,after_main函数进入最后面的VM段。该VM段作为程序中第一个VM段,CodeVirtualizer会解密后续所有的字节码,而后进入VM。VM会调用一系列函数。Vape首先检查与服务器的通讯是否正常,若正常,则State=3,而后进入登录检查
下面两个函数均是递归调用自己,而他们的Caller在after_main函数中(被VM了)。
check_Valid_LoginState_VM 大致伪代码
bool check_Valid_LoginState_VM()
{
char hwid[0x60];
size_t i;
DWORD v;
srand(time(0));
// example hwid: 1234abcd
getUserHwid(&hwid);
// Xor Hwid with byte 0x0A, After: ;89>khin
// 此处VM执行时间很长,效率较低,每次xor都要遍历一遍hwid
for(i = 0; i < strlen(hwid); i++)
hwid[i] ^= 0x0A;
log("3\n");
log(hwid + "\n");
log("V4");
// 与另一个线程同步,用于HttpRequest
SetEvent();
WaitForSingleObject();
retval = OtherHttpReqFunction();
strstr(retval, "ok");
v = rand();
Dword2Hex(v);
// Lazy To Reverse... That's not important part.
return true;
}
UserSettings
检查完登录状态后,下来会获取用户设定。UserToken是登陆后服务器返回的值。
// Hidden C++ exception states: #wind=2
__int64 GetUserSettings()
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
user_token = get_user_token();
sub_140014DB0(v23, "/api/v1/%s/settings/load/global", user_token);
sub_1400082B0(v14, v23);
sub_1400082B0(v13, "online.vape.gg");
sub_140017800(v22, v13, v14);
sub_1400089E0(v13);
sub_1400089E0(v14);
v3 = 0;
try
{
v8 = sub_14001E800(v19, 0LL);
LOBYTE(v1) = 1;
sub_140020520(v21, v22, v8, v1, 0);
sub_1400082B0(v15, "successful");
v4 = sub_14001E850(v21, v15);
sub_1400089E0(v15);
if ( v4 )
{
v9 = sub_140020680(v21, "successful");
if ( sub_1400206C0(v9) )
{
sub_1400082B0(v16, "data");
v5 = sub_14001E850(v21, v16);
sub_1400089E0(v16);
if ( v5 )
{
v10 = sub_140020680(v21, "data");
sub_14001E9A0(v20, v10);
sub_1400082B0(v17, "cache");
v6 = sub_14001E850(v20, v17);
sub_1400089E0(v17);
if ( v6 )
{
v11 = sub_140020680(v20, "cache");
settings_cache = sub_1400206C0(v11);
v3 = 1;
}
sub_1400082B0(v18, "firstRun");
v7 = sub_14001E850(v20, v18);
sub_1400089E0(v18);
if ( v7 )
{
v12 = sub_140020680(v20, "firstRun");
byte_140421A49 = sub_1400206C0(v12);
v3 = 1;
}
sub_14001E8E0(v20);
}
}
}
sub_14001E8E0(v21);
}
catch ( std::exception )
{
}
if ( !v3 )
{
settings_cache = 0;
byte_140421A49 = 0;
}
return sub_1400089E0(v22);
}
创建CacheDir(.vapeclient)
创建完Dir后,Vape会检测一次是否发生错误,如果没有错误,进入Inject阶段。
Injection
bool InjectMain()
{
__int64 v1; // rax
int v2; // [rsp+20h] [rbp-38h]
__int64 v3; // [rsp+28h] [rbp-30h]
_BYTE v4[16]; // [rsp+30h] [rbp-28h] BYREF
setStage(4u);
v2 = sub_14000DCA0();
if ( v2 == 1 )
{
setStage(5u);
LODWORD(v1) = write_process((__int64)v4, hProcess, (void *)listening_port);
v3 = v1;
if ( !v1 )
sub_14009A6D0((__int64)"Failed to inject\n"
"Use a supported Minecraft version and client listed on the FAQ of the website");
return v3 != 0;
}
else
{
if ( v2 == 8 )
sub_14009A6D0((__int64)"Couldn't connect to server.\n"
"This may caused by an anti-virus or router blocking the connection, or another network issue. 1");
if ( v2 == 9 )
sub_14009A6D0((__int64)"Couldn't connect to server.\n"
"This may caused by an anti-virus or router blocking the connection, or another network issue. 2");
if ( v2 == 3 )
sub_14009A6D0((__int64)"Error connecting");
if ( v2 == 4 )
sub_14009A6D0((__int64)"No data read");
if ( v2 == 5 )
sub_14009A6D0((__int64)"Error 5");
if ( v2 == 6 )
sub_14009A6D0((__int64)"Error 1");
if ( v2 == 7 )
sub_14009A6D0((__int64)"Error -1");
return 0;
}
}
int __fastcall write_process(__int64 a1, void *a2, void *a3)
{
return WriteHackedClientToJava(a2, *(void **)a1, *(_DWORD *)(a1 + 8), a3);
}
int __cdecl WriteHackedClientToJava(void *ppExcept, void *pType, int adjectives, void *pBuildObj)
{
HMODULE ModuleHandleW; // rax
DWORD v5; // eax
DWORD v6; // eax
DWORD v7; // eax
DWORD LastError; // eax
int v10; // [rsp+40h] [rbp-48h]
char *lpBaseAddress; // [rsp+48h] [rbp-40h]
int v12; // [rsp+50h] [rbp-38h]
DWORD flOldProtect; // [rsp+64h] [rbp-24h] BYREF
DWORD ThreadId; // [rsp+68h] [rbp-20h] BYREF
v12 = 0;
ThreadId = 0;
ModuleHandleW = GetModuleHandleW(L"ntdll.dll");
NtWriteVirtualMemory = (__int64)GetProcAddress(ModuleHandleW, "NtWriteVirtualMemory");
if ( ppExcept && pType && adjectives )
{
v10 = sub_14009B710(pType);
if ( v10 )
{
lpBaseAddress = (char *)VirtualAllocEx(ppExcept, 0LL, (unsigned int)adjectives, 0x3000u, 4u);
if ( lpBaseAddress )
{
if ( WriteProcessMemory(ppExcept, lpBaseAddress, pType, (unsigned int)adjectives, 0LL) )
{
flOldProtect = 0;
if ( VirtualProtectEx(ppExcept, lpBaseAddress, (unsigned int)adjectives, 0x40u, &flOldProtect) )
{
return (unsigned int)CreateRemoteThread(
ppExcept,
0LL,
0x100000uLL,
(LPTHREAD_START_ROUTINE)&lpBaseAddress[v10],
pBuildObj,
0,
&ThreadId);
}
else
{
LastError = GetLastError();
printf("e4 %i\n", LastError);
}
}
else
{
v7 = GetLastError();
printf("e3 %i\n", v7);
}
}
else
{
v6 = GetLastError();
printf("e2 %i\n", v6);
}
}
else
{
v5 = GetLastError();
printf("e1 %i\n", v5);
}
}
return v12;
}
代码均已贴出,意思不言而喻,通过打开Minecraft进程,随后写入PE文件,然后进行远程线程注入,启动特定的函数,并且传入本地监听的端口号。
其中,sub_14000DCA0函数是VM的,对于这个函数,大概率是下载或者是解密即将注入的PE文件,这不是我们分析的重点。
至此,主程序的大部分功能已经分析完毕,对于Socket通信,我们留在注入的进程中进行讲解。
InjectedStub - 注入的DLL
我们可以从主程序的WriteProcessMemory过程中很容易地Dump出注入的DLL文件,并且从CreateRemoteThread中可以很容易得到即将运行的线程从哪个地址开始。
PE ReflectiveLoader
我们发现DLL导出了一个名为tim的函数,线程也是从这里开始运行的。
void (__fastcall *__fastcall tim(void *a1))(__int64, __int64, void *)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]
v44 = 0LL;
v45 = 0LL;
v42 = 0LL;
v46 = 0LL;
for ( i = sub_180023D10(); ; --i )
{
if ( *i == 0x5A4D )
{
v35 = *(i + 60);
if ( v35 >= 0x40 && v35 < 0x400 && *(i + v35) == 17744 )
break;
}
}
for ( j = NtCurrentPeb()->Ldr->InMemoryOrderModuleList.Flink; j; j = j->Flink )
{
Flink = j[5].Flink;
Blink = j[4].Blink;
v15 = 0;
do
{
v16 = sub_180023CA0(v15);
if ( LOBYTE(Flink->Flink) < 0x61u )
Flink_low = LOBYTE(Flink->Flink);
else
Flink_low = LOBYTE(Flink->Flink) - 32;
v15 = Flink_low + v16;
Flink = (Flink + 1);
--Blink;
}
while ( Blink );
if ( v15 == 0x6A4ABC5B ) // Kernel32_Hash
{
v6 = j[2].Flink;
v32 = (v6 + *(&v6[8].Blink + SHIDWORD(v6[3].Blink)));
v37 = (v6 + v32[8]);
v40 = (v6 + v32[9]);
v4 = 3;
while ( v4 )
{
v31 = sub_180023CB0(v6 + *v37);
if ( v31 == 0xEC0E4E8E || v31 == 0x7C0DFCAA || v31 == 0x91AFCA54 )
{
v39 = (v6 + 4 * *v40 + v32[7]);
if ( v31 == 0xEC0E4E8E )
{
v44 = (v6 + *v39);
}
else if ( v31 == 0x7C0DFCAA )
{
v45 = (v6 + *v39);
}
else
{
v42 = (v6 + *v39);
}
--v4;
}
++v37;
++v40;
}
}
else if ( v15 == 1023043677 )
{
v7 = j[2].Flink;
v33 = (v7 + *(&v7[8].Blink + SHIDWORD(v7[3].Blink)));
v38 = (v7 + v33[8]);
v41 = (v7 + v33[9]);
v5 = 1;
while ( v5 )
{
if ( sub_180023CB0(v7 + *v38) == 1397492408 )
{
v46 = (v7 + *(&v7->Flink + 4 * *v41 + v33[7]));
--v5;
}
++v38;
++v41;
}
}
if ( v44 && v45 && v42 && v46 )
break;
}
v36 = *(i + 60) + i;
v8 = (v42)(0LL, *(v36 + 80), 12288LL, 64LL);
v10 = *(v36 + 84);
v25 = i;
for ( k = v8; v10--; ++k )
*k = *v25++;
v11 = (v36 + *(v36 + 20) + 24);
v43 = *(v36 + 6);
while ( v43-- )
{
v26 = (v11[3] + v8);
v18 = (v11[5] + i);
v21 = v11[4];
while ( v21-- )
*v26++ = *v18++;
v11 += 10;
}
for ( m = (*(v36 + 144) + v8); m[3]; m += 5 )
{
v29 = v44(m[3] + v8);
v22 = (*m + v8);
for ( n = (m[4] + v8); *n; ++n )
{
if ( v22 && *v22 < 0 )
{
v34 = *(*(v29 + 60) + v29 + 136) + v29;
*n = *(*(v34 + 28) + v29 + 4 * (*v22 - *(v34 + 16))) + v29;
}
else
{
*n = (v45)(v29, *n + v8 + 2);
}
if ( v22 )
++v22;
}
}
v30 = v8 - *(v36 + 48);
if ( *(v36 + 180) )
{
for ( ii = (*(v36 + 176) + v8); ii[1]; ii = (ii + ii[1]) )
{
v13 = *ii + v8;
v27 = (ii[1] - 8) / 2;
for ( jj = ii + 2; v27--; ++jj )
{
switch ( HIBYTE(*jj) >> 4 )
{
case 10:
*(v13 + (*jj & 0xFFF)) += v30;
break;
case 3:
*(v13 + (*jj & 0xFFF)) += v30;
break;
case 1:
*(v13 + (*jj & 0xFFF)) += WORD1(v30);
break;
case 2:
*(v13 + (*jj & 0xFFF)) += v30;
break;
}
}
}
}
v14 = (*(v36 + 40) + v8);
(v46)(-1LL, 0LL, 0LL);
v14(v8, 1LL, a1);
return v14;
}
根据分析,我们可以确定这是一个自定义的PE加载器,其代码与 ReflectiveDLLInjection/dll/src/ReflectiveLoader.c at 5198e33b5b2cc6ab70c7bd2439c25a022e90ae1e · rapid7/ReflectiveDLLInjection 非常相似,这对我们分析十分有益。
在加载完后,根据代码分析,它将会调用PE的OEP,对于DLL来说,也就是DllMain。
非常遗憾,DllMain也是加了VM的,我们去虚拟化后继续分析。
JNI_GetCreatedJavaVMs
Vape通过本函数获取当前的JVM。
随后调用其他初始化流程,这里还调用了System.gc(),可能是为了清理一些痕迹。
加载jvm.dll,使用BoyerMooreSearch在Jvm.dll空间内寻找字节序列 99 1E E0,并将其Patch掉,但是本分支在我的电脑上并未执行到,这三个字节暂时不知道有什么用途。
后续发现,这个Get_jvm函数是由VM中调用的,而不是这段代码。
FetchJByteCode
StubDll通过链接本地Socket,发送特定payload,使主程序回应所有的要注入的Java class。所有的class均通过socket传递到客户端,随后,客户端通过DefineClass注册类,通过RegisterNatives注册所有的Native函数。
Dump Classes
通过X64dbg提供的Breakpoint Expression功能,断DefineClass即可。
savedata C:\Users\Administrator\Desktop\vape\dump\\{utf8@rdx}.class, r9, Dword(rsp+0x20); run
RegisterNatives
Vape分几次注册Natives函数,所有注册函数的调用均在VM中完成,所有的注册均在DefineClass完成之后。
第一次注册了主类中的所有重要Native函数
关于RegisterNatives的参数传递,官方解释如下
jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);
Registers native methods with the class specified by the clazz
argument. The methods
parameter specifies an array of JNINativeMethod
structures that contain the names, signatures, and function pointers of the native methods. The name
and signature
fields of the JNINativeMethod structure are pointers to modified UTF-8 strings. The nMethods
parameter specifies the number of native methods in the array. The JNINativeMethod
structure is defined as follows:
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
The function pointers nominally must have the following signature:
ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);
于是我们可以看懂下面的这些注册
第一批
000000F85A0FF6F0 000002E7813869F0 ði8.ç... "exit"
000000F85A0FF6F8 000002E781382880 .(8.ç... "(Z)V"
000000F85A0FF700 000002E780558190 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+4470
000000F85A0FF708 000002E7805FD8BC ¼Ø_.ç... "dc"
000000F85A0FF710 000002E781365AC0 ÀZ6.ç... "()V"
000000F85A0FF718 000002E780558200 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+44E0
000000F85A0FF720 000002E7805FD8C4 ÄØ_.ç... "fs"
000000F85A0FF728 000002E78137A1C0 À¡7.ç... "()V"
000000F85A0FF730 000002E780558230 0.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4510
000000F85A0FF738 000002E7805FD8CC ÌØ_.ç... "gc"
000000F85A0FF740 000002E78138B3D0 г8.ç... "(Ljava/lang/String;)Ljava/lang/Class;"
000000F85A0FF748 000002E780558270 p.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4550
000000F85A0FF750 000002E7805FD8F8 øØ_.ç... "gt"
000000F85A0FF758 000002E781365430 0T6.ç... "(Ljava/lang/String;)[B"
000000F85A0FF760 000002E7805582E0 à.U.ç... vape.unsigned __int64 __cdecl tim(void *)+45C0
000000F85A0FF768 000002E7805FD918 .Ù_.ç... "gs"
000000F85A0FF770 000002E78138AA90 .ª8.ç... "()Ljava/lang/String;"
000000F85A0FF778 000002E780558300 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+45E0
000000F85A0FF780 000002E7805FD938 8Ù_.ç... "ss"
000000F85A0FF788 000002E781380210 ..8.ç... "(Ljava/lang/String;)V"
000000F85A0FF790 000002E780558330 0.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4610
000000F85A0FF798 000002E781380470 p.8.ç... "ss_2"
000000F85A0FF7A0 000002E7813828B0 °(8.ç... "(Ljava/lang/String;)I"
000000F85A0FF7A8 000002E7805583C0 À.U.ç... vape.unsigned __int64 __cdecl tim(void *)+46A0
000000F85A0FF7B0 000002E78135DE30 0Þ5.ç... "ss_3"
000000F85A0FF7B8 000002E781382270 p"8.ç... "(Ljava/lang/String;)I"
000000F85A0FF7C0 000002E780558470 p.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4750
000000F85A0FF7C8 000002E78137EF50 Pï7.ç... "gcj"
000000F85A0FF7D0 000002E78137B6F0 ð¶7.ç... "(Ljava/lang/String;)Ljava/lang/Class;"
000000F85A0FF7D8 000002E7805585E0 à.U.ç... vape.unsigned __int64 __cdecl tim(void *)+48C0
000000F85A0FF7E0 000002E78138AB00 .«8.ç... "gcs"
000000F85A0FF7E8 000002E781389970 p.8.ç... "(Ljava/lang/Class;)Ljava/lang/String;"
000000F85A0FF7F0 000002E780558670 p.U.ç... L"襌⑄䠘咉ဤ襈圈腈胬"
000000F85A0FF7F8 000002E7805FD9F8 øÙ_.ç... "cs"
000000F85A0FF800 000002E781394030 0@9.ç... "(I)Ljava/lang/String;"
000000F85A0FF808 000002E7805587F0 ð.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4AD0
000000F85A0FF810 000002E7805FDA18 .Ú_.ç... "rl"
000000F85A0FF818 000002E78133E080 .à3.ç... "()V"
000000F85A0FF820 000002E7805369C0 ÀiS.ç... vape.000002E7805369C0
000000F85A0FF828 000002E7805FDA20 Ú_.ç... "mb"
000000F85A0FF830 000002E78137F310 .ó7.ç... "(I)V"
000000F85A0FF838 000002E780558590 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+4870
000000F85A0FF840 000002E78138C4C0 ÀÄ8.ç... "grh"
000000F85A0FF848 000002E781380690 ..8.ç... "()Ljava/lang/Object;"
000000F85A0FF850 000002E780558830 0.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4B10
000000F85A0FF858 000002E78137E9A0 é7.ç... "cpy"
000000F85A0FF860 000002E781368A60 `.6.ç... "(Ljava/lang/String;)V"
000000F85A0FF868 000002E780558850 P.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4B30
000000F85A0FF870 000002E781365BA0 [6.ç... "gks"
000000F85A0FF878 000002E781393A30 0:9.ç... "(I)S"
000000F85A0FF880 000002E780558A30 0.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4D10
000000F85A0FF888 000002E7805FDA74 tÚ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A9D54
000000F85A0FF890 000002E78137AD30 0.7.ç... "(Ljava/lang/String;)V"
000000F85A0FF898 000002E7805589D0 Ð.U.ç... vape.unsigned __int64 __cdecl tim(void *)+4CB0
000000F85A0FF8A0 000002E78133D1A0 Ñ3.ç... "gco"
000000F85A0FF8A8 000002E781394D80 .M9.ç... "(Ljava/lang/Class;)[Ljava/lang/Object;"
000000F85A0FF8B0 000002E780558AB0 °.U.ç... L"襌⑄䠘咉ဤ襈圈腈胬"
000000F85A0FF8B8 000002E78137E7C0 Àç7.ç... "trn"
000000F85A0FF8C0 000002E78135F9F0 ðù5.ç... "(DDD)[D"
000000F85A0FF8C8 000002E780558CA0 .U.ç... vape.unsigned __int64 __cdecl tim(void *)+4F80
000000F85A0FF8D0 000002E78138B5E0 àµ8.ç... "gcb"
000000F85A0FF8D8 000002E78137F3D0 Ðó7.ç... "(Ljava/lang/Class;)[B"
000000F85A0FF8E0 000002E7805593C0 À.U.ç... vape.unsigned __int64 __cdecl tim(void *)+56A0
000000F85A0FF8E8 000002E78137A7E0 à§7.ç... "scb"
000000F85A0FF8F0 000002E781386BB0 °k8.ç... "(Ljava/lang/Class;[B)I"
000000F85A0FF8F8 000002E780559570 p.U.ç... vape.unsigned __int64 __cdecl tim(void *)+5850
000000F85A0FF900 000002E781382A10 .*8.ç... "gcf"
000000F85A0FF908 000002E78138DED0 ÐÞ8.ç... "(Ljava/lang/Class;)[Ljava/lang/String;"
000000F85A0FF910 000002E7805596F0 ð.U.ç... vape.unsigned __int64 __cdecl tim(void *)+59D0
000000F85A0FF918 000002E7813870D0 Ðp8.ç... "gcm"
000000F85A0FF920 000002E78136D020 Ð6.ç... "(Ljava/lang/Class;)[Ljava/lang/String;"
000000F85A0FF928 000002E780559890 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+5B70
000000F85A0FF930 000002E7805FDB70 pÛ_.ç... "ds"
000000F85A0FF938 000002E781380B40 @.8.ç... "(ILjava/lang/String;DDI)I"
000000F85A0FF940 000002E780559A30 0.U.ç... L"襌䐠䒉ᠤ襈䠐䲉ࠤ荈壬荈⑼xݵ쀳鋩"
000000F85A0FF948 000002E781386D40 @m8.ç... "gsw"
000000F85A0FF950 000002E781382730 0'8.ç... "(ILjava/lang/String;)D"
000000F85A0FF958 000002E780559AF0 ð.U.ç... vape.unsigned __int64 __cdecl tim(void *)+5DD0
000000F85A0FF960 000002E78139D030 0Ð9.ç... "gsh"
000000F85A0FF968 000002E781368AE0 à.6.ç... "(ILjava/lang/String;)D"
000000F85A0FF970 000002E780559BA0 .U.ç... vape.unsigned __int64 __cdecl tim(void *)+5E80
000000F85A0FF978 000002E781387040 @p8.ç... "smd"
000000F85A0FF980 000002E78133D120 Ñ3.ç... "(II)V"
000000F85A0FF988 000002E780559D10 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+5FF0
000000F85A0FF990 000002E7805FDBDC ÜÛ_.ç... "gk"
000000F85A0FF998 000002E78136D950 PÙ6.ç... "()I"
000000F85A0FF9A0 000002E780559DC0 À.U.ç... vape.unsigned __int64 __cdecl tim(void *)+60A0
000000F85A0FF9A8 000002E7805FDBE4 äÛ_.ç... "gp"
000000F85A0FF9B0 000002E78137FAF0 ðú7.ç... "(Ljava/lang/String;)Ljava/lang/String;"
000000F85A0FF9B8 000002E780559DE0 à.U.ç... vape.unsigned __int64 __cdecl tim(void *)+60C0
000000F85A0FF9C0 000002E7805FDC10 .Ü_.ç... "su"
000000F85A0FF9C8 000002E78137C0B0 °À7.ç... "(Ljava/lang/String;)V"
000000F85A0FF9D0 000002E780559F10 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+61F0
000000F85A0FF9D8 000002E7805FDC30 0Ü_.ç... "iv"
000000F85A0FF9E0 000002E78135D2E0 àÒ5.ç... "()Z"
000000F85A0FF9E8 000002E780559F90 ..U.ç... vape.unsigned __int64 __cdecl tim(void *)+6270
000000F85A0FF9F0 000002E78137F9A0 ù7.ç... "gvc"
000000F85A0FF9F8 000002E7813821C0 À!8.ç... "(Ljava/lang/String;)Ljava/lang/Class;"
000000F85A0FFA00 000002E780559FB0 °.U.ç... vape.unsigned __int64 __cdecl tim(void *)+6290
000000F85A0FFA08 000002E78135DF50 Pß5.ç... "gmv"
000000F85A0FFA10 000002E781387C60 `|8.ç... "()I"
000000F85A0FFA18 000002E78055A1D0 СU.ç... vape.unsigned __int64 __cdecl tim(void *)+64B0
000000F85A0FFA20 000002E78137A230 0¢7.ç... "rsc"
000000F85A0FFA28 000002E781386C20 l8.ç... "()V"
000000F85A0FFA30 000002E78055A1F0 ð¡U.ç... vape.unsigned __int64 __cdecl tim(void *)+64D0
000000F85A0FFA38 000002E7805FDC78 xÜ_.ç... "mf"
000000F85A0FFA40 000002E781367880 .x6.ç... "(IILjava/lang/String;)I"
000000F85A0FFA48 000002E780559C40 @.U.ç... vape.unsigned __int64 __cdecl tim(void *)+5F20
000000F85A0FFA50 000002E7813670B0 °p6.ç... "updc"
000000F85A0FFA58 000002E78137A440 @¤7.ç... "(Ljava/lang/String;Ljava/lang/String;)V"
000000F85A0FFA60 000002E78055A220 ¢U.ç... vape.unsigned __int64 __cdecl tim(void *)+6500
000000F85A0FFA68 000002E78136D170 pÑ6.ç... "mvk"
000000F85A0FFA70 000002E781387C00 .|8.ç... "(II)I"
000000F85A0FFA78 000002E78055A240 @¢U.ç... vape.unsigned __int64 __cdecl tim(void *)+6520
000000F85A0FFA80 000002E78135BC50 P¼5.ç... "gkn"
000000F85A0FFA88 000002E78137B570 pµ7.ç... "(J)Ljava/lang/String;"
000000F85A0FFA90 000002E78055A270 p¢U.ç... vape.unsigned __int64 __cdecl tim(void *)+6550
000000F85A0FFA98 000002E7805FDCF0 ðÜ_.ç... "rs"
000000F85A0FFAA0 000002E78138BAE0 àº8.ç... "(IDD)V"
000000F85A0FFAA8 000002E78055A300 .£U.ç... vape.unsigned __int64 __cdecl tim(void *)+65E0
000000F85A0FFAB0 000002E78136EC40 @ì6.ç... "gts"
000000F85A0FFAB8 000002E781395050 PP9.ç... "()I"
000000F85A0FFAC0 000002E78055A4C0 À¤U.ç... vape.unsigned __int64 __cdecl tim(void *)+67A0
000000F85A0FFAC8 000002E781366C50 Pl6.ç... "sts"
000000F85A0FFAD0 000002E7813823A0 #8.ç... "()I"
000000F85A0FFAD8 000002E78055A520 ¥U.ç... vape.unsigned __int64 __cdecl tim(void *)+6800
000000F85A0FFAE0 000002E7813675B0 °u6.ç... "trs"
000000F85A0FFAE8 000002E78137A5D0 Ð¥7.ç... "(I)V"
000000F85A0FFAF0 000002E78055A560 `¥U.ç... vape.unsigned __int64 __cdecl tim(void *)+6840
000000F85A0FFAF8 000002E7813658A0 X6.ç... "gfb"
000000F85A0FFB00 000002E781380610 ..8.ç... "(Ljava/lang/String;)[B"
000000F85A0FFB08 000002E78055A590 .¥U.ç... vape.unsigned __int64 __cdecl tim(void *)+6870
000000F85A0FFB10 000002E78137F920 ù7.ç... "gtcf"
000000F85A0FFB18 000002E781389EB0 °.8.ç... "(Ljava/lang/Object;II)Z"
000000F85A0FFB20 000002E78055A6D0 ЦU.ç... vape.unsigned __int64 __cdecl tim(void *)+69B0
000000F85A0FFB28 000002E78133D1D0 ÐÑ3.ç... "gat"
000000F85A0FFB30 000002E78138B470 p´8.ç... "()Ljava/lang/String;"
000000F85A0FFB38 000002E78055A660 `¦U.ç... vape.unsigned __int64 __cdecl tim(void *)+6940
000000F85A0FFB40 000002E78137FFF0 ðÿ7.ç... "scm"
000000F85A0FFB48 000002E78137B660 `¶7.ç... "(Ljava/lang/String;Ljava/lang/String;)V"
000000F85A0FFB50 000002E78055A930 0©U.ç... vape.unsigned __int64 __cdecl tim(void *)+6C10
000000F85A0FFB58 000002E781389DC0 À.8.ç... "gls"
000000F85A0FFB60 000002E78136D110 .Ñ6.ç... "()[Z"
000000F85A0FFB68 000002E78055A820 ¨U.ç... vape.unsigned __int64 __cdecl tim(void *)+6B00
000000F85A0FFB70 000002E78137A320 £7.ç... "sce"
000000F85A0FFB78 000002E78139E3B0 °ã9.ç... "(Ljava/lang/String;)V"
000000F85A0FFB80 000002E78055AA90 .ªU.ç... vape.unsigned __int64 __cdecl tim(void *)+6D70
第二批
000000F85A0FF590 000002E7805FC584 .Å_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8864
000000F85A0FF598 000002E7805FC588 .Å_.ç... "(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V"
000000F85A0FF5A0 000002E780548590 ..T.ç... L"襌䐠䒉ᠤ襈䠐䲉ࠤ荈磬ᢹ"
000000F85A0FF5A8 000002E7805FC5C4 ÄÅ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A88A4
000000F85A0FF5B0 000002E7805FC5C8 ÈÅ_.ç... "(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V"
000000F85A0FF5B8 000002E780548700 ..T.ç... L"襌䐠䒉ᠤ襈䠐䲉ࠤ荈棬ᢹ"
000000F85A0FF5C0 000002E7805FC604 .Æ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A88E4
000000F85A0FF5C8 000002E7805FC608 .Æ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)V"
000000F85A0FF5D0 000002E780546720 gT.ç... vape.000002E780546720
000000F85A0FF5D8 000002E7805FC634 4Æ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8914
000000F85A0FF5E0 000002E7805FC638 8Æ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)Z"
000000F85A0FF5E8 000002E780546890 .hT.ç... vape.000002E780546890
000000F85A0FF5F0 000002E7805FC664 dÆ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8944
000000F85A0FF5F8 000002E7805FC668 hÆ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)C"
000000F85A0FF600 000002E780546A10 .jT.ç... vape.000002E780546A10
000000F85A0FF608 000002E7805FC694 .Æ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8974
000000F85A0FF610 000002E7805FC698 .Æ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)S"
000000F85A0FF618 000002E780546B90 .kT.ç... vape.000002E780546B90
000000F85A0FF620 000002E7805FC6C4 ÄÆ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A89A4
000000F85A0FF628 000002E7805FC6C8 ÈÆ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)I"
000000F85A0FF630 000002E780546D10 .mT.ç... vape.000002E780546D10
000000F85A0FF638 000002E7805FC6F4 ôÆ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A89D4
000000F85A0FF640 000002E7805FC6F8 øÆ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)J"
000000F85A0FF648 000002E780546E90 .nT.ç... vape.000002E780546E90
000000F85A0FF650 000002E7805FC724 $Ç_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8A04
000000F85A0FF658 000002E7805FC728 (Ç_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)F"
000000F85A0FF660 000002E780547010 .pT.ç... vape.000002E780547010
000000F85A0FF668 000002E7805FC754 TÇ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8A34
000000F85A0FF670 000002E7805FC758 XÇ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)D"
000000F85A0FF678 000002E780547190 .qT.ç... vape.000002E780547190
000000F85A0FF680 000002E7805FC784 .Ç_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8A64
000000F85A0FF688 000002E7805FC788 .Ç_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"
000000F85A0FF690 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF698 000002E7805FC7C4 ÄÇ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8AA4
000000F85A0FF6A0 000002E7805FC7C8 ÈÇ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[Z"
000000F85A0FF6A8 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF6B0 000002E7805FC7F4 ôÇ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8AD4
000000F85A0FF6B8 000002E7805FC7F8 øÇ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[C"
000000F85A0FF6C0 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF6C8 000002E7805FC824 $È_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8B04
000000F85A0FF6D0 000002E7805FC828 (È_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[S"
000000F85A0FF6D8 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF6E0 000002E7805FC854 TÈ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8B34
000000F85A0FF6E8 000002E7805FC858 XÈ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[I"
000000F85A0FF6F0 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF6F8 000002E7805FC884 .È_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8B64
000000F85A0FF700 000002E7805FC888 .È_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[J"
000000F85A0FF708 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF710 000002E7805FC8B4 ´È_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8B94
000000F85A0FF718 000002E7805FC8B8 ¸È_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[F"
000000F85A0FF720 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF728 000002E7805FC8E4 äÈ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8BC4
000000F85A0FF730 000002E7805FC8E8 èÈ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[D"
000000F85A0FF738 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF740 000002E7805FC914 .É_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8BF4
000000F85A0FF748 000002E7805FC918 .É_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[Ljava/lang/Object;"
000000F85A0FF750 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FF758 000002E7805FC954 TÉ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8C34
000000F85A0FF760 000002E7805FC958 XÉ_.ç... "(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V"
000000F85A0FF768 000002E780548810 ..T.ç... L"襌䐠䒉ᠤ襈䠐䲉ࠤ荈磬₹"
000000F85A0FF770 000002E7805FC994 .É_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8C74
000000F85A0FF778 000002E7805FC998 .É_.ç... "(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V"
000000F85A0FF780 000002E780548990 ..T.ç... L"襌䐠䒉ᠤ襈䠐䲉ࠤ荈棬₹"
000000F85A0FF788 000002E7805FC9D4 ÔÉ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8CB4
000000F85A0FF790 000002E7805FC9D8 ØÉ_.ç... "(ILjava/lang/Object;)Z"
000000F85A0FF798 000002E780547610 .vT.ç... vape.000002E780547610
000000F85A0FF7A0 000002E7805FC9F0 ðÉ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8CD0
000000F85A0FF7A8 000002E7805FC9F8 øÉ_.ç... "(ILjava/lang/Object;)C"
000000F85A0FF7B0 000002E7805476B0 °vT.ç... vape.000002E7805476B0
000000F85A0FF7B8 000002E7805FCA10 .Ê_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8CF0
000000F85A0FF7C0 000002E7805FCA18 .Ê_.ç... "(ILjava/lang/Object;)S"
000000F85A0FF7C8 000002E780547750 PwT.ç... vape.000002E780547750
000000F85A0FF7D0 000002E7805FCA30 0Ê_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8D10
000000F85A0FF7D8 000002E7805FCA38 8Ê_.ç... "(ILjava/lang/Object;)I"
000000F85A0FF7E0 000002E7805477F0 ðwT.ç... vape.000002E7805477F0
000000F85A0FF7E8 000002E7805FCA50 PÊ_.ç... vape.unsigned __int64 __cdecl tim(void *)+A8D30
000000F85A0FF7F0 000002E7805FCA58 XÊ_.ç... "(ILjava/lang/Object;)J"
000000F85A0FF7F8 000002E780547890 .xT.ç... vape.000002E780547890
000000F85A0FF800 000002E7805FCA70 pÊ_.ç... "aa"
000000F85A0FF808 000002E7805FCA78 xÊ_.ç... "(ILjava/lang/Object;)F"
000000F85A0FF810 000002E780547930 0yT.ç... vape.000002E780547930
000000F85A0FF818 000002E7805FCA90 .Ê_.ç... "bb"
000000F85A0FF820 000002E7805FCA98 .Ê_.ç... "(ILjava/lang/Object;)D"
000000F85A0FF828 000002E7805479E0 àyT.ç... vape.000002E7805479E0
000000F85A0FF830 000002E7805FCAB0 °Ê_.ç... "cc"
000000F85A0FF838 000002E7805FCAB8 ¸Ê_.ç... "(ILjava/lang/Object;)Ljava/lang/Object;"
000000F85A0FF840 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF848 000002E7805FCAE0 àÊ_.ç... "dd"
000000F85A0FF850 000002E7805FCAE8 èÊ_.ç... "(ILjava/lang/Object;)[Z"
000000F85A0FF858 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF860 000002E7805FCB00 .Ë_.ç... "ee"
000000F85A0FF868 000002E7805FCB08 .Ë_.ç... "(ILjava/lang/Object;)[C"
000000F85A0FF870 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF878 000002E7805FCB20 Ë_.ç... "ff"
000000F85A0FF880 000002E7805FCB28 (Ë_.ç... "(ILjava/lang/Object;)[S"
000000F85A0FF888 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF890 000002E7805FCB40 @Ë_.ç... "gg"
000000F85A0FF898 000002E7805FCB48 HË_.ç... "(ILjava/lang/Object;)[I"
000000F85A0FF8A0 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF8A8 000002E7805FCB60 `Ë_.ç... "hh"
000000F85A0FF8B0 000002E7805FCB68 hË_.ç... "(ILjava/lang/Object;)[J"
000000F85A0FF8B8 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF8C0 000002E7805FCB80 .Ë_.ç... "ii"
000000F85A0FF8C8 000002E7805FCB88 .Ë_.ç... "(ILjava/lang/Object;)[F"
000000F85A0FF8D0 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF8D8 000002E7805FCBA0 Ë_.ç... "jj"
000000F85A0FF8E0 000002E7805FCBA8 ¨Ë_.ç... "(ILjava/lang/Object;)[D"
000000F85A0FF8E8 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF8F0 000002E7805FCBC0 ÀË_.ç... "kk"
000000F85A0FF8F8 000002E7805FCBC8 ÈË_.ç... "(ILjava/lang/Object;)[Ljava/lang/Object;"
000000F85A0FF900 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FF908 000002E7805FCBF4 ôË_.ç... "ll"
000000F85A0FF910 000002E7805FCBF8 øË_.ç... "(ILjava/lang/Object;Z)V"
000000F85A0FF918 000002E780547BD0 Ð{T.ç... vape.000002E780547BD0
000000F85A0FF920 000002E7805FCC10 .Ì_.ç... "mm"
000000F85A0FF928 000002E7805FCC18 .Ì_.ç... "(ILjava/lang/Object;C)V"
000000F85A0FF930 000002E780547C70 p|T.ç... vape.000002E780547C70
000000F85A0FF938 000002E7805FCC30 0Ì_.ç... "nn"
000000F85A0FF940 000002E7805FCC38 8Ì_.ç... "(ILjava/lang/Object;S)V"
000000F85A0FF948 000002E780547D10 .}T.ç... vape.000002E780547D10
000000F85A0FF950 000002E7805FCC50 PÌ_.ç... "oo"
000000F85A0FF958 000002E7805FCC58 XÌ_.ç... "(ILjava/lang/Object;I)V"
000000F85A0FF960 000002E780547DB0 °}T.ç... vape.000002E780547DB0
000000F85A0FF968 000002E7805FCC70 pÌ_.ç... "pp"
000000F85A0FF970 000002E7805FCC78 xÌ_.ç... "(ILjava/lang/Object;J)V"
000000F85A0FF978 000002E780547E50 P~T.ç... vape.000002E780547E50
000000F85A0FF980 000002E7805FCC90 .Ì_.ç... "qq"
000000F85A0FF988 000002E7805FCC98 .Ì_.ç... "(ILjava/lang/Object;F)V"
000000F85A0FF990 000002E780547EF0 ð~T.ç... vape.000002E780547EF0
000000F85A0FF998 000002E7805FCCB0 °Ì_.ç... "rr"
000000F85A0FF9A0 000002E7805FCCB8 ¸Ì_.ç... "(ILjava/lang/Object;D)V"
000000F85A0FF9A8 000002E780547F90 ..T.ç... vape.000002E780547F90
000000F85A0FF9B0 000002E7805FCCD0 ÐÌ_.ç... "ss"
000000F85A0FF9B8 000002E7805FCCD8 ØÌ_.ç... "(ILjava/lang/Object;Ljava/lang/Object;)V"
000000F85A0FF9C0 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FF9C8 000002E7805FCD04 .Í_.ç... "tt"
000000F85A0FF9D0 000002E7805FCD08 .Í_.ç... "(ILjava/lang/Object;[Z)V"
000000F85A0FF9D8 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FF9E0 000002E7805FCD24 $Í_.ç... "uu"
000000F85A0FF9E8 000002E7805FCD28 (Í_.ç... "(ILjava/lang/Object;[C)V"
000000F85A0FF9F0 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FF9F8 000002E7805FCD44 DÍ_.ç... "vv"
000000F85A0FFA00 000002E7805FCD48 HÍ_.ç... "(ILjava/lang/Object;[S)V"
000000F85A0FFA08 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFA10 000002E7805FCD64 dÍ_.ç... "ww"
000000F85A0FFA18 000002E7805FCD68 hÍ_.ç... "(ILjava/lang/Object;[I)V"
000000F85A0FFA20 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFA28 000002E7805FCD84 .Í_.ç... "xx"
000000F85A0FFA30 000002E7805FCD88 .Í_.ç... "(ILjava/lang/Object;[J)V"
000000F85A0FFA38 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFA40 000002E7805FCDA4 ¤Í_.ç... "yy"
000000F85A0FFA48 000002E7805FCDA8 ¨Í_.ç... "(ILjava/lang/Object;[F)V"
000000F85A0FFA50 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFA58 000002E7805FCDC4 ÄÍ_.ç... "zz"
000000F85A0FFA60 000002E7805FCDC8 ÈÍ_.ç... "(ILjava/lang/Object;[D)V"
000000F85A0FFA68 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFA70 000002E7805FCDE4 äÍ_.ç... "aaa"
000000F85A0FFA78 000002E7805FCDE8 èÍ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)V"
000000F85A0FFA80 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFA88 000002E7805FCE14 .Î_.ç... "bbb"
000000F85A0FFA90 000002E7805FCE18 .Î_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)V"
000000F85A0FFA98 000002E780548170 p.T.ç... vape.000002E780548170
000000F85A0FFAA0 000002E7805FCE44 DÎ_.ç... "ccc"
000000F85A0FFAA8 000002E7805FCE48 HÎ_.ç... "(ILjava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;"
000000F85A0FFAB0 000002E780548450 P.T.ç... vape.000002E780548450
000000F85A0FFAB8 000002E7805FCE84 .Î_.ç... "ddd"
000000F85A0FFAC0 000002E7805FCE88 .Î_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)B"
000000F85A0FFAC8 000002E780547310 .sT.ç... vape.000002E780547310
000000F85A0FFAD0 000002E7805FCEB4 ´Î_.ç... "eee"
000000F85A0FFAD8 000002E7805FCEB8 ¸Î_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)[B"
000000F85A0FFAE0 000002E780547490 .tT.ç... vape.000002E780547490
000000F85A0FFAE8 000002E7805FCEE4 äÎ_.ç... "fff"
000000F85A0FFAF0 000002E7805FCEE8 èÎ_.ç... "(ILjava/lang/Object;)B"
000000F85A0FFAF8 000002E780547A90 .zT.ç... vape.000002E780547A90
000000F85A0FFB00 000002E7805FCF00 .Ï_.ç... "ggg"
000000F85A0FFB08 000002E7805FCF08 .Ï_.ç... "(ILjava/lang/Object;B)V"
000000F85A0FFB10 000002E780548030 0.T.ç... vape.000002E780548030
000000F85A0FFB18 000002E7805FCF20 Ï_.ç... "hhh"
000000F85A0FFB20 000002E7805FCF28 (Ï_.ç... "(ILjava/lang/Object;)[B"
000000F85A0FFB28 000002E780547B30 0{T.ç... vape.000002E780547B30
000000F85A0FFB30 000002E7805FCF40 @Ï_.ç... "iii"
000000F85A0FFB38 000002E7805FCF48 HÏ_.ç... "(ILjava/lang/Object;[B)V"
000000F85A0FFB40 000002E7805480D0 Ð.T.ç... vape.000002E7805480D0
000000F85A0FFB48 000002E7805FCF64 dÏ_.ç... "jjj"
000000F85A0FFB50 000002E7805FCF68 hÏ_.ç... "(ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"
000000F85A0FFB58 000002E7805482E0 à.T.ç... vape.000002E7805482E0
000000F85A0FFB60 000002E7805FCFA4 ¤Ï_.ç... "gfn"
000000F85A0FFB68 000002E7805FCFA8 ¨Ï_.ç... "(I)Ljava/lang/String;"
000000F85A0FFB70 000002E780548AB0 °.T.ç... vape.000002E780548AB0
000000F85A0FFB78 000002E7805FCFC0 ÀÏ_.ç... "gmn"
000000F85A0FFB80 000002E7805FCFC8 ÈÏ_.ç... "(I)Ljava/lang/String;"
000000F85A0FFB88 000002E780548BB0 °.T.ç... vape.000002E780548BB0
如果Hook的话,x64dbg.exe迭代这些内容并不方便,我们采用下面这种方案来简便输出。
我们找到RegisterNatives的实现,可以观察到它自带一个for循环,我们找准点Hook输出即可。
JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods,
jint nMethods))
HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
jint ret = 0;
DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// There are no restrictions on native code registering native methods,
// which allows agents to redefine the bindings to native methods, however
// we issue a warning if any code running outside of the boot/platform
// loader is rebinding any native methods in classes loaded by the
// boot/platform loader that are in named modules. That will catch changes
// to platform classes while excluding classes added to the bootclasspath.
bool do_warning = false;
// Only instanceKlasses can have native methods
if (k->is_instance_klass()) {
oop cl = k->class_loader();
InstanceKlass* ik = InstanceKlass::cast(k);
// Check for a platform class
if ((cl == NULL || SystemDictionary::is_platform_class_loader(cl)) &&
ik->module()->is_named()) {
Klass* caller = thread->security_get_caller_class(1);
// If no caller class, or caller class has a different loader, then
// issue a warning below.
do_warning = (caller == NULL) || caller->class_loader() != cl;
}
}
for (int index = 0; index < nMethods; index++) {
const char* meth_name = methods[index].name;
const char* meth_sig = methods[index].signature;
int meth_name_len = (int)strlen(meth_name);
// The class should have been loaded (we have an instance of the class
// passed in) so the method and signature should already be in the symbol
// table. If they're not there, the method doesn't exist.
TempNewSymbol name = SymbolTable::probe(meth_name, meth_name_len);
TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
if (name == NULL || signature == NULL) {
ResourceMark rm(THREAD);
stringStream st;
st.print("Method %s.%s%s not found", k->external_name(), meth_name, meth_sig);
// Must return negative value on failure
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
}
if (do_warning) {
ResourceMark rm(THREAD);
log_warning(jni, resolve)("Re-registering of platform native method: %s.%s%s "
"from code in a different classloader", k->external_name(), meth_name, meth_sig);
}
bool res = Method::register_native(k, name, signature,
(address) methods[index].fnPtr, THREAD);
if (!res) {
ret = -1;
break;
}
}
return ret;
JNI_END
At Jvm.dll FileOffset=0x492BB0
RegisterNative('{utf8@[r12-0x10]}', '{utf8@[r12-0x8]}', {p:[r12]} (RVA=0x{x:([r12] - ModBase)}))
RegisterNative('exit', '(Z)V', 0000021E80EF8190 (RVA=0x28190))
RegisterNative('dc', '()V', 0000021E80EF8200 (RVA=0x28200))
RegisterNative('fs', '()V', 0000021E80EF8230 (RVA=0x28230))
RegisterNative('gc', '(Ljava/lang/String;)Ljava/lang/Class;', 0000021E80EF8270 (RVA=0x28270))
RegisterNative('gt', '(Ljava/lang/String;)[B', 0000021E80EF82E0 (RVA=0x282E0))
RegisterNative('gs', '()Ljava/lang/String;', 0000021E80EF8300 (RVA=0x28300))
RegisterNative('ss', '(Ljava/lang/String;)V', 0000021E80EF8330 (RVA=0x28330))
RegisterNative('ss_2', '(Ljava/lang/String;)I', 0000021E80EF83C0 (RVA=0x283C0))
RegisterNative('ss_3', '(Ljava/lang/String;)I', 0000021E80EF8470 (RVA=0x28470))
RegisterNative('gcj', '(Ljava/lang/String;)Ljava/lang/Class;', 0000021E80EF85E0 (RVA=0x285E0))
RegisterNative('gcs', '(Ljava/lang/Class;)Ljava/lang/String;', 0000021E80EF8670 (RVA=0x28670))
RegisterNative('cs', '(I)Ljava/lang/String;', 0000021E80EF87F0 (RVA=0x287F0))
RegisterNative('rl', '()V', 0000021E80ED69C0 (RVA=0x69C0))
RegisterNative('mb', '(I)V', 0000021E80EF8590 (RVA=0x28590))
RegisterNative('grh', '()Ljava/lang/Object;', 0000021E80EF8830 (RVA=0x28830))
RegisterNative('cpy', '(Ljava/lang/String;)V', 0000021E80EF8850 (RVA=0x28850))
RegisterNative('gks', '(I)S', 0000021E80EF8A30 (RVA=0x28A30))
RegisterNative('p', '(Ljava/lang/String;)V', 0000021E80EF89D0 (RVA=0x289D0))
RegisterNative('gco', '(Ljava/lang/Class;)[Ljava/lang/Object;', 0000021E80EF8AB0 (RVA=0x28AB0))
RegisterNative('trn', '(DDD)[D', 0000021E80EF8CA0 (RVA=0x28CA0))
RegisterNative('gcb', '(Ljava/lang/Class;)[B', 0000021E80EF93C0 (RVA=0x293C0))
RegisterNative('scb', '(Ljava/lang/Class;[B)I', 0000021E80EF9570 (RVA=0x29570))
RegisterNative('gcf', '(Ljava/lang/Class;)[Ljava/lang/String;', 0000021E80EF96F0 (RVA=0x296F0))
RegisterNative('gcm', '(Ljava/lang/Class;)[Ljava/lang/String;', 0000021E80EF9890 (RVA=0x29890))
RegisterNative('ds', '(ILjava/lang/String;DDI)I', 0000021E80EF9A30 (RVA=0x29A30))
RegisterNative('gsw', '(ILjava/lang/String;)D', 0000021E80EF9AF0 (RVA=0x29AF0))
RegisterNative('gsh', '(ILjava/lang/String;)D', 0000021E80EF9BA0 (RVA=0x29BA0))
RegisterNative('smd', '(II)V', 0000021E80EF9D10 (RVA=0x29D10))
RegisterNative('gk', '()I', 0000021E80EF9DC0 (RVA=0x29DC0))
RegisterNative('gp', '(Ljava/lang/String;)Ljava/lang/String;', 0000021E80EF9DE0 (RVA=0x29DE0))
RegisterNative('su', '(Ljava/lang/String;)V', 0000021E80EF9F10 (RVA=0x29F10))
RegisterNative('iv', '()Z', 0000021E80EF9F90 (RVA=0x29F90))
RegisterNative('gvc', '(Ljava/lang/String;)Ljava/lang/Class;', 0000021E80EF9FB0 (RVA=0x29FB0))
RegisterNative('gmv', '()I', 0000021E80EFA1D0 (RVA=0x2A1D0))
RegisterNative('rsc', '()V', 0000021E80EFA1F0 (RVA=0x2A1F0))
RegisterNative('mf', '(IILjava/lang/String;)I', 0000021E80EF9C40 (RVA=0x29C40))
RegisterNative('updc', '(Ljava/lang/String;Ljava/lang/String;)V', 0000021E80EFA220 (RVA=0x2A220))
RegisterNative('mvk', '(II)I', 0000021E80EFA240 (RVA=0x2A240))
RegisterNative('gkn', '(J)Ljava/lang/String;', 0000021E80EFA270 (RVA=0x2A270))
RegisterNative('rs', '(IDD)V', 0000021E80EFA300 (RVA=0x2A300))
RegisterNative('gts', '()I', 0000021E80EFA4C0 (RVA=0x2A4C0))
RegisterNative('sts', '()I', 0000021E80EFA520 (RVA=0x2A520))
RegisterNative('trs', '(I)V', 0000021E80EFA560 (RVA=0x2A560))
RegisterNative('gfb', '(Ljava/lang/String;)[B', 0000021E80EFA590 (RVA=0x2A590))
RegisterNative('gtcf', '(Ljava/lang/Object;II)Z', 0000021E80EFA6D0 (RVA=0x2A6D0))
RegisterNative('gat', '()Ljava/lang/String;', 0000021E80EFA660 (RVA=0x2A660))
RegisterNative('scm', '(Ljava/lang/String;Ljava/lang/String;)V', 0000021E80EFA930 (RVA=0x2A930))
RegisterNative('gls', '()[Z', 0000021E80EFA820 (RVA=0x2A820))
RegisterNative('sce', '(Ljava/lang/String;)V', 0000021E80EFAA90 (RVA=0x2AA90))
RegisterNative('a', '(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V', 0000021E80EE8590 (RVA=0x18590))
RegisterNative('b', '(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V', 0000021E80EE8700 (RVA=0x18700))
RegisterNative('c', '(ILjava/lang/Object;[Ljava/lang/Object;)V', 0000021E80EE6720 (RVA=0x16720))
RegisterNative('d', '(ILjava/lang/Object;[Ljava/lang/Object;)Z', 0000021E80EE6890 (RVA=0x16890))
RegisterNative('e', '(ILjava/lang/Object;[Ljava/lang/Object;)C', 0000021E80EE6A10 (RVA=0x16A10))
RegisterNative('f', '(ILjava/lang/Object;[Ljava/lang/Object;)S', 0000021E80EE6B90 (RVA=0x16B90))
RegisterNative('g', '(ILjava/lang/Object;[Ljava/lang/Object;)I', 0000021E80EE6D10 (RVA=0x16D10))
RegisterNative('h', '(ILjava/lang/Object;[Ljava/lang/Object;)J', 0000021E80EE6E90 (RVA=0x16E90))
RegisterNative('i', '(ILjava/lang/Object;[Ljava/lang/Object;)F', 0000021E80EE7010 (RVA=0x17010))
RegisterNative('j', '(ILjava/lang/Object;[Ljava/lang/Object;)D', 0000021E80EE7190 (RVA=0x17190))
RegisterNative('k', '(ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('l', '(ILjava/lang/Object;[Ljava/lang/Object;)[Z', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('m', '(ILjava/lang/Object;[Ljava/lang/Object;)[C', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('n', '(ILjava/lang/Object;[Ljava/lang/Object;)[S', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('o', '(ILjava/lang/Object;[Ljava/lang/Object;)[I', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('p', '(ILjava/lang/Object;[Ljava/lang/Object;)[J', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('q', '(ILjava/lang/Object;[Ljava/lang/Object;)[F', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('r', '(ILjava/lang/Object;[Ljava/lang/Object;)[D', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('s', '(ILjava/lang/Object;[Ljava/lang/Object;)[Ljava/lang/Object;', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('t', '(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V', 0000021E80EE8810 (RVA=0x18810))
RegisterNative('u', '(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V', 0000021E80EE8990 (RVA=0x18990))
RegisterNative('v', '(ILjava/lang/Object;)Z', 0000021E80EE7610 (RVA=0x17610))
RegisterNative('w', '(ILjava/lang/Object;)C', 0000021E80EE76B0 (RVA=0x176B0))
RegisterNative('x', '(ILjava/lang/Object;)S', 0000021E80EE7750 (RVA=0x17750))
RegisterNative('y', '(ILjava/lang/Object;)I', 0000021E80EE77F0 (RVA=0x177F0))
RegisterNative('z', '(ILjava/lang/Object;)J', 0000021E80EE7890 (RVA=0x17890))
RegisterNative('aa', '(ILjava/lang/Object;)F', 0000021E80EE7930 (RVA=0x17930))
RegisterNative('bb', '(ILjava/lang/Object;)D', 0000021E80EE79E0 (RVA=0x179E0))
RegisterNative('cc', '(ILjava/lang/Object;)Ljava/lang/Object;', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('dd', '(ILjava/lang/Object;)[Z', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('ee', '(ILjava/lang/Object;)[C', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('ff', '(ILjava/lang/Object;)[S', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('gg', '(ILjava/lang/Object;)[I', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('hh', '(ILjava/lang/Object;)[J', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('ii', '(ILjava/lang/Object;)[F', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('jj', '(ILjava/lang/Object;)[D', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('kk', '(ILjava/lang/Object;)[Ljava/lang/Object;', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('ll', '(ILjava/lang/Object;Z)V', 0000021E80EE7BD0 (RVA=0x17BD0))
RegisterNative('mm', '(ILjava/lang/Object;C)V', 0000021E80EE7C70 (RVA=0x17C70))
RegisterNative('nn', '(ILjava/lang/Object;S)V', 0000021E80EE7D10 (RVA=0x17D10))
RegisterNative('oo', '(ILjava/lang/Object;I)V', 0000021E80EE7DB0 (RVA=0x17DB0))
RegisterNative('pp', '(ILjava/lang/Object;J)V', 0000021E80EE7E50 (RVA=0x17E50))
RegisterNative('qq', '(ILjava/lang/Object;F)V', 0000021E80EE7EF0 (RVA=0x17EF0))
RegisterNative('rr', '(ILjava/lang/Object;D)V', 0000021E80EE7F90 (RVA=0x17F90))
RegisterNative('ss', '(ILjava/lang/Object;Ljava/lang/Object;)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('tt', '(ILjava/lang/Object;[Z)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('uu', '(ILjava/lang/Object;[C)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('vv', '(ILjava/lang/Object;[S)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('ww', '(ILjava/lang/Object;[I)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('xx', '(ILjava/lang/Object;[J)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('yy', '(ILjava/lang/Object;[F)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('zz', '(ILjava/lang/Object;[D)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('aaa', '(ILjava/lang/Object;[Ljava/lang/Object;)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('bbb', '(ILjava/lang/Object;[Ljava/lang/Object;)V', 0000021E80EE8170 (RVA=0x18170))
RegisterNative('ccc', '(ILjava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;', 0000021E80EE8450 (RVA=0x18450))
RegisterNative('ddd', '(ILjava/lang/Object;[Ljava/lang/Object;)B', 0000021E80EE7310 (RVA=0x17310))
RegisterNative('eee', '(ILjava/lang/Object;[Ljava/lang/Object;)[B', 0000021E80EE7490 (RVA=0x17490))
RegisterNative('fff', '(ILjava/lang/Object;)B', 0000021E80EE7A90 (RVA=0x17A90))
RegisterNative('ggg', '(ILjava/lang/Object;B)V', 0000021E80EE8030 (RVA=0x18030))
RegisterNative('hhh', '(ILjava/lang/Object;)[B', 0000021E80EE7B30 (RVA=0x17B30))
RegisterNative('iii', '(ILjava/lang/Object;[B)V', 0000021E80EE80D0 (RVA=0x180D0))
RegisterNative('jjj', '(ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;', 0000021E80EE82E0 (RVA=0x182E0))
RegisterNative('gfn', '(I)Ljava/lang/String;', 0000021E80EE8AB0 (RVA=0x18AB0))
RegisterNative('gmn', '(I)Ljava/lang/String;', 0000021E80EE8BB0 (RVA=0x18BB0))
后续即可分析这些Native函数,只不过他们大部分都加了VM。
在注入后,主程序即可退出
部分 Native 函数解析
RegisterNative('cpy', '(Ljava/lang/String;)V', 0000021E80EF8850 (RVA=0x28850))
void __fastcall Java_a_a_cpy(JNIEnv *a1, __int64 a2, __int64 a3)
{
int StringLength; // eax
unsigned int v4; // eax
_BYTE *v5; // [rsp+30h] [rbp-58h]
__int64 v6; // [rsp+38h] [rbp-50h]
HGLOBAL hMem; // [rsp+40h] [rbp-48h]
StringLength = JNI_GetStringLength(a1, a3);
v5 = sub_180032644(StringLength);
v4 = JNI_GetStringLength(a1, a3);
JNI_GetStringUTFRegion(a1, a3, 0, v4, v5);
v5[JNI_GetStringLength(a1, a3)] = 0;
v6 = -1LL;
do
++v6;
while ( v5[v6] );
hMem = GlobalAlloc(2u, v6 + 1);
qmemcpy(GlobalLock(hMem), v5, v6 + 1);
GlobalUnlock(hMem);
OpenClipboard(0LL);
EmptyClipboard();
SetClipboardData(1u, hMem);
CloseClipboard();
j_j_free(v5);
}
RegisterNative('rs', '(IDD)V', 0000021E80EFA300 (RVA=0x2A300))
void Java_a_a_rs(JNIEnv *env, jclass clazz, jint mode, jdouble width, jdouble height)
{
BOOL changed;
if ( !mode )
{
glGetFloatv(0xBA6u, ¶ms);
glGetFloatv(0xBA7u, &m);
}
if ( mode == 2 )
glVertex2d(width, height);
// Is Window Size Changed
changed = last_width != width || last_height != height;
if ( changed && !mode )
{
// ReInit
a = glGenLists(1);
glNewList(a, GL_COMPILE /* 0x1300 */);
glMatrixMode(GL_PROJECTION /* 0x1701 */);
glLoadIdentity();
glOrtho(0.0d, width, height, 0.0d, 1500.0d, 3000.0d);
glMatrixMode(GL_MODELVIEW /* 0x1700 */);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -2000.0f);
glEndList();
}
else
{
if ( mode )
{
glMatrixMode(0x1701u);
glLoadMatrixf(&m);
glMatrixMode(0x1700u);
glLoadMatrixf(¶ms);
}
else
{
glCallList(list);
}
// Update Window Width & Height
last_width = width;
last_height = height;
}
}
RegisterNative('mf', '(IILjava/lang/String;)I', 0000021E80EF9C40 (RVA=0x29C40))
void __fastcall Java_a_a_mf(JNIEnv *a1, jclass clazz, jint a3, jint a4, jstring fontName)
{
void *p; // [rsp+20h] [rbp-28h]
FontStruct *FontTexture; // [rsp+28h] [rbp-20h]
char *StringUTFChars; // [rsp+30h] [rbp-18h]
jint v9; // [rsp+60h] [rbp+18h] BYREF
jint v10; // [rsp+68h] [rbp+20h]
v10 = a4;
v9 = a3;
StringUTFChars = (char *)JNI_GetStringUTFChars(a1, fontName, 0LL);
p = cxx::new(0x27120uLL);
if ( p )
{
memzero(p, 0x27120uLL);
FontTexture = loadFontTexture((FontStruct *)p, StringUTFChars, v10);
}
else
{
FontTexture = 0LL;
}
*(_QWORD *)sub_18002B460((__int64)&unk_180C16EC0, (__int64)&v9) = FontTexture;
sub_18000DD60(a1, fontName, StringUTFChars);
sub_18002B460((__int64)&unk_180C16EC0, (__int64)&v9);
}
FontStruct *__fastcall loadFontTexture(FontStruct *font, char *fontName, int fontSize)
{
char *v3; // rax
__int64 v4; // rcx
unsigned __int8 v5; // dl
int v6; // eax
__int64 v7; // rax
char *v8; // rax
__int64 v9; // rcx
__int64 v10; // rdx
int v11; // eax
__int64 v12; // rax
void *v13; // rax
int v15; // [rsp+50h] [rbp-468h]
int v16; // [rsp+50h] [rbp-468h]
char v17; // [rsp+57h] [rbp-461h]
int j; // [rsp+58h] [rbp-460h]
int v19; // [rsp+5Ch] [rbp-45Ch]
_BYTE *pixels; // [rsp+60h] [rbp-458h]
__int64 v21; // [rsp+78h] [rbp-440h]
__int64 v22; // [rsp+80h] [rbp-438h]
char i; // [rsp+90h] [rbp-428h] BYREF
_BYTE v24[15]; // [rsp+91h] [rbp-427h] BYREF
_BYTE v25[1024]; // [rsp+A0h] [rbp-418h] BYREF
font->fontHandle = 0LL;
memset(font->charWidths, 0, 0x9C40uLL);
memset(&font->charHeights[16], 0, 0x9C40uLL);
memset(&font->bitmapData[128], 0, 0x13880uLL);
font[1].charWidths[24] = fontSize;
font->textureResource = (void *)sub_18002DF60(512LL, 512LL, 1LL);
memset(v25, 0, sizeof(v25));
sub_18000E080(v25, "C:\\Windows\\Fonts\\%s.ttf", fontName);
v3 = fontName;
v4 = "proxima" - fontName;
while ( 1 )
{
v5 = *v3;
if ( *v3 != v3[v4] )
break;
++v3;
if ( !v5 )
{
v6 = 0;
goto LABEL_6;
}
}
v6 = v5 < (unsigned __int8)v3[v4] ? -1 : 1;
LABEL_6:
if ( v6 )
{
v8 = fontName;
v9 = "proximabd" - fontName;
while ( 1 )
{
v10 = (unsigned __int8)*v8;
if ( (_BYTE)v10 != v8[v9] )
break;
++v8;
if ( !(_BYTE)v10 )
{
v11 = 0;
goto LABEL_13;
}
}
v11 = (unsigned __int8)v10 < (unsigned __int8)v8[v9] ? -1 : 1;
LABEL_13:
if ( v11 )
{
v13 = (void *)sub_18002EEF0(font->textureResource, v10, v25);
}
else
{
v12 = sub_180023B80();
v13 = sub_18002EF90((__int64)font->textureResource, (float)fontSize, v12, 63116LL);
}
font->fontHandle = v13;
}
else
{
v7 = sub_180023B70();
font->fontHandle = sub_18002EF90((__int64)font->textureResource, (float)fontSize, v7, 43240LL);
}
for ( i = 0; i != 127; ++i )
{
texture_font_load_face((_QWORD *)font->fontHandle, (__int64)&i);
v21 = sub_18002E220(font->fontHandle, &i);
font->charWidths[i] = *(_DWORD *)(v21 + 32);
}
for ( v24[0] = 0; v24[0] != 127; ++v24[0] )
{
texture_font_load_face((_QWORD *)font->fontHandle, (__int64)v24);
v22 = sub_18002E220(font->fontHandle, v24);
*(float *)&font->charHeights[v24[0] + 16] = (float)*(int *)(v22 + 28);
}
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(0xBE2u);
glBlendFunc(0x302u, 0x303u);
glGenTextures(1, (GLuint *)&font[1].charWidths[25]);
glBindTexture(0xDE1u, font[1].charWidths[25]);
glTexParameteri(0xDE1u, 0x2802u, 10496);
glTexParameteri(0xDE1u, 0x2803u, 10496);
glTexParameteri(0xDE1u, 0x2800u, 9729);
glTexParameteri(0xDE1u, 0x2801u, 9729);
v19 = *(_DWORD *)(*((_QWORD *)font->fontHandle + 1) + 16LL) * *(_DWORD *)(*((_QWORD *)font->fontHandle + 1) + 8LL);
pixels = j_cxx::new(4 * v19);
v15 = 0;
for ( j = 0; j < v19; ++j )
{
v17 = *(_BYTE *)(*(_QWORD *)(*((_QWORD *)font->fontHandle + 1) + 48LL) + j);
pixels[v15] = -1;
v16 = v15 + 1;
pixels[v16++] = -1;
pixels[v16++] = -1;
pixels[v16] = v17;
v15 = v16 + 1;
}
glTexImage2D(
0xDE1u,
0,
6408,
*(_DWORD *)(*((_QWORD *)font->fontHandle + 1) + 8LL),
*(_DWORD *)(*((_QWORD *)font->fontHandle + 1) + 16LL),
0,
0x1908u,
0x1401u,
pixels);
return font;
}
Vape.Jar
Zkm混淆,笔者目前没有接触过Java反混淆领域,暂时不写,具体附件在“相关附件”栏,Java大手子们可以尝试。
分析 VapeLite
主程序
主程序采用 Themida 加壳,有反调试,API Wrapper,资源压缩等,部分代码虚拟化。脱壳后即可继续分析。
VapeLite主程序与VapeV4主程序大差不差,很多函数都是一样的,比如提权(SeDebugPrivilege),本地Socket监听,RenderingUI,检测Minecraft存活,Hwid,Login等等......
在注入后会建立Socket与客户端保持联系,这一点与V4也一样。
VapeLite与VapeV4不同的点在于,它不会检查(也无法检查)Minecraft是否被注入过,因为客户端被注入后没有和VapeV4客户端一样打开一个pipe供检查。
所以,我们只需要分析它的远程线程注入,拿到StubDll即可,其他无需分析。
InjectedStub - 注入的DLL
What's same
采用一样的方案,Hook WriteProcessMemory即可完整dump出VapeLite.dll。
VapeLite.dll中还是有"Vape Lite"这样特殊的字符串供检测,只要对java.exe内存全量扫描即可查出。
与VapeV4.dll不同的是,VapeLite.dll没有加壳也没有进行代码虚拟化,极大方便了我们的分析。
本人认为可以将VapeLite.dll与VapeV4.dll对比分析,毕竟这两个dll的大部分代码都相同,比如下面就是DllMain,这在VapeV4.dll中是完全虚拟化的。
通过分析我们可以得知,TCPPort依旧是从主程序传来(CreateRemoteThread),之后在ReflectiveLoader工作完毕后传入DllEntry的Reserved参数中。
随后创建线程,使用该Port作为线程参数值,传入新线程,从而传入DllMain。
DllMain中依旧采用JNI_GetCreatedJavaVMs获取当前VM。
GetForgeVersion
CustomClassLoader
这个函数是从 native 端构造 Java 类路径,然后通过自定义 ClassLoader 加载对应类,并返回其全局引用(jclass 或对象),并将引用缓存到结构体中以复用。
jobject __fastcall vapeClassLoader(struct_a1 *a1, JNIEnv *a2, const char *str)
{
int v7; // r9d
__int64 len; // r8
__int64 v9; // rax
char *v10; // rdx
unsigned __int64 v11; // rcx
__int64 v13; // rax
char *v14; // rdx
unsigned __int64 v15; // rax
jstring (**p_NewStringUTF)(JNIEnv *, const char *); // rax
va_list param_str; // rax
jobject v18; // rax
jobject v19; // rax
jobject v20; // rcx
jobject v21; // rbx
jclass v22; // rax
_BYTE *v23; // rdx
jobject v24[2]; // [rsp+30h] [rbp-438h] BYREF
char Buffer[1024]; // [rsp+40h] [rbp-428h] BYREF
if ( !*&a1->gap0[8] )
return 0LL;
memset(Buffer, 0, sizeof(Buffer));
vsprintf(Buffer, "%s", str);
v7 = 0;
len = 0LL;
v9 = -1LL;
do
++v9; // strlen
while ( Buffer[v9] );
if ( v9 )
{
v10 = Buffer;
do
{
if ( *v10 == '.' ) // translate . -> /
*v10 = '/';
len = (len + 1);
++v10;
v11 = -1LL;
do
++v11;
while ( Buffer[v11] );
}
while ( len < v11 );
}
if ( !a1->byte56 )
goto LABEL_23;
v13 = -1LL;
do // // strlen
++v13;
while ( Buffer[v13] );
if ( v13 ) // Translate / -> .
{
v14 = Buffer;
do
{
if ( *v14 == '/' )
*v14 = '.';
++v7;
++v14;
v15 = -1LL;
do
++v15;
while ( Buffer[v15] );
}
while ( v7 < v15 );
p_NewStringUTF = &(*a2)->NewStringUTF;
}
else
{
LABEL_23:
p_NewStringUTF = &(*a2)->NewStringUTF;
}
param_str = (*p_NewStringUTF)(a2, Buffer, len);
v18 = JNI_CallObjectMethodV(a2, *&a1->gap0[8], *&a1->gap30[24], param_str);
v19 = (*a2)->NewGlobalRef(a2, v18);
v24[0] = v19;
v20 = v19;
v21 = v19;
if ( v19 )
goto LABEL_28;
if ( (*a2)->ExceptionOccurred(a2) )
(*a2)->ExceptionClear(a2);
v22 = (*a2)->FindClass(a2, Buffer);
v19 = (*a2)->NewGlobalRef(a2, v22);
v24[0] = v19;
v20 = v19;
v21 = v19;
if ( v19 )
{
LABEL_28:
v23 = *&a1->gap30[8];
if ( v23 == *&a1->gap30[16] )
{
sub_180011B30(a1->gap30, v23, v24);
return v21;
}
else
{
*v23 = v19;
*&a1->gap30[8] += 8LL;
}
}
return v20;
}
UpperClassFinder
如果是 Minecraft 类,走上面的ClassLoader,否则走FindClass。
jobject __fastcall upperClassFinder(__int64 a1, JNIEnv *a2, const char *a3)
{
__int64 v6; // rdx
__int64 v7; // rcx
__int64 v8; // rbx
unsigned __int64 v9; // rbx
jobject result; // rax
char *v11; // rdx
__int64 v12; // rsi
__int64 v13; // r14
__int64 v14; // rdx
__int64 v15; // rbx
jobject **v16; // r9
jobject **v17; // r11
jobject *v18; // r10
__int64 v19; // rcx
__int64 v20; // rax
char *v21; // r8
int v22; // ecx
char v23; // al
size_t v24; // rdi
__int64 v25; // rdx
__int64 v26; // rcx
unsigned __int64 v27; // rdi
__int64 v28; // rax
bool v29; // zf
__int64 v30; // rax
__int64 v31; // rdx
char v32; // al
__int64 v33; // rax
__int64 v34; // rax
unsigned __int64 v35; // rax
__int64 v36; // rdx
__int64 v37; // rcx
unsigned __int64 v38; // rbx
char Buffer[2048]; // [rsp+20h] [rbp-E0h] BYREF
char Str[2048]; // [rsp+820h] [rbp+720h] BYREF
if ( *(a1 + 8) && ((*(a1 + 96) - *(a1 + 88)) & 0xFFFFFFFFFFFFFFF8uLL) == 0 )
{
memset(Buffer, 0, sizeof(Buffer));
if ( *a3 == 76 )
{
vsprintf(Buffer, "%s", a3 + 1);
v8 = -1LL;
do
++v8;
while ( Buffer[v8] );
v9 = v8 - 1;
if ( v9 >= 0x800 )
sub_18018EAB0(v7, v6);
Buffer[v9] = 0;
}
else
{
vsprintf(Buffer, "%s", a3);
}
if ( strstr(Buffer, "net/minecraft") )
return vapeClassLoader(a1, a2, Buffer);
else
return (*a2)->FindClass(a2, Buffer);
}
memset(Str, 0, sizeof(Str));
v11 = "%s";
if ( *a3 != 76 )
v11 = "L%s;";
vsprintf(Str, v11, a3);
v12 = 0LL;
v13 = 0LL;
v15 = -1LL;
if ( strstr(Str, "net/minecraft") || *(a1 + 33) && (strstr(Str, "netty") || strstr(Str, "lwjgl")) )
{
v16 = *(a1 + 88);
v17 = *(a1 + 96);
if ( v16 != v17 )
{
while ( 1 )
{
v18 = *v16;
v19 = -1LL;
v20 = (*v16 + 1);
do
++v19;
while ( *(v20 + v19) );
if ( v19 )
{
v21 = &Str[-v20];
do
{
v22 = v21[v20];
v14 = *v20 - v22;
if ( v14 )
break;
++v20;
}
while ( v22 );
if ( !v14 )
break;
}
if ( ++v16 == v17 )
goto LABEL_29;
}
v13 = *v18;
if ( *v18 )
return v13;
}
}
LABEL_29:
v23 = Str[0];
if ( Str[0] != 91 )
{
LABEL_40:
if ( v23 == 76 )
{
LABEL_47:
if ( !v13 )
{
memset(Buffer, 0, sizeof(Buffer));
if ( *a3 == 76 )
{
vsprintf(Buffer, "%s", a3 + 1);
do
++v15;
while ( Buffer[v15] );
v38 = v15 - 1;
if ( v38 >= 0x800 )
sub_18018EAB0(v37, v36);
Buffer[v38] = 0;
}
else
{
vsprintf(Buffer, "%s", a3);
}
if ( strstr(Buffer, "net/minecraft") )
return vapeClassLoader(a1, a2, Buffer);
else
return (*a2)->FindClass(a2, Buffer);
}
return v13;
}
LABEL_41:
Buffer[0] = 76;
do
{
v32 = Str[v12];
Buffer[++v12] = v32;
}
while ( v32 );
v33 = -1LL;
do
++v33;
while ( Str[v33] );
v34 = v33 + 1;
Buffer[v34] = 59;
v35 = v34 + 1;
if ( v35 >= 0x400 )
sub_18018EAB0(Str, v14);
Buffer[v35] = 0;
v13 = sub_180026130(a1, Buffer);
goto LABEL_47;
}
if ( Str[1] != 76 )
goto LABEL_41;
strcpy(Buffer, Str);
v24 = -1LL;
do
++v24;
while ( Str[v24] );
memcpy(Buffer, &Str[1], v24);
v27 = v24 - 2;
if ( v27 >= 0x400 )
sub_18018EAB0(v26, v25);
Buffer[v27] = 0;
Buffer[0] = 91;
v28 = -1LL;
do
v29 = Buffer[++v28] == 0;
while ( !v29 );
Buffer[v28] = 59;
v30 = -1LL;
do
v29 = Buffer[++v30] == 0;
while ( !v29 );
v31 = *(a1 + 40);
Buffer[v30 + 1] = 48;
result = vapeClassLoader(a1, *(v31 + 8), Buffer);
v13 = result;
if ( !result )
{
v23 = Str[0];
goto LABEL_40;
}
return result;
}
注册 EventBus
Event是现代CheatClient或者mod的基本要素,用于在游戏特定时期来完成特定功能,Vape Lite兼容多版本,所以对于这里的操作有不同种类,下面我们简单分析一下ForgeVersion在26上下的操作。
ForgeVersion < 26
注入一个随机名称的类
InlineHook Lwjgl64.dll
我们可以看出,Display.getAvailableDisplayModes() 这个函数的处理流程在Lwjgl64的Native中,而VapeLite.dll采用InlineHook,使此函数的Native处理流程重定向到了自己的处理函数 lwjgl_getAvailableDisplayModes_Callback。
lwjgl_getAvailableDisplayModes_Callback
ForgeVersion >= 26
注入a.class
RegisterNative
if ( gForgeVersion >= 26 )
{
v6[0] = "invoke";
v6[1] = "(Lnet/minecraftforge/eventbus/api/Event;)V";
v6[2] = sub_180101670;
sub_180102790(*(a1 + 168), *(a1 + 160), v6, 1LL);
}
其他操作(注册 Event, 获取基本类)
__int64 __fastcall sub_180100390(__int64 a1, JNIEnv *a2)
{
_OWORD *v2; // rax
_OWORD *v3; // rax
_OWORD *v4; // rax
_OWORD *v5; // rax
_OWORD *v6; // rax
int v7; // eax
int v8; // eax
int v9; // eax
int v10; // eax
int v11; // eax
int v12; // eax
_OWORD *v13; // rax
_OWORD *v14; // rax
_OWORD *v15; // rax
_OWORD *v16; // rax
int v17; // eax
int v18; // eax
int v19; // eax
int v20; // eax
__int64 v21; // rax
_OWORD *v22; // rax
_OWORD *v23; // rax
_OWORD *v24; // rax
_OWORD *v25; // rax
int v26; // eax
int v27; // eax
int v28; // eax
int v29; // eax
struct_a1 *v30; // rax
struct_a1 *v31; // rax
struct_a1 *v32; // rax
struct_a1 *v33; // rax
struct_a1 *v34; // rax
struct_a1 *v35; // rax
struct_a1 *v36; // rax
struct_a1 *v37; // rax
struct_a1 *v38; // rax
struct_a1 *v39; // rax
struct_a1 *v40; // rax
struct_a1 *v41; // rax
struct_a1 *v42; // rax
struct_a1 *v43; // rax
struct_a1 *v44; // rax
int v45; // eax
_OWORD *v46; // rax
_OWORD *v47; // rax
_OWORD *v48; // rax
_OWORD *v49; // rax
struct_a1 *v50; // rax
int v51; // eax
__int64 v52; // rax
_OWORD *v53; // rax
_OWORD *v54; // rax
_OWORD *v55; // rax
_OWORD *v56; // rax
struct_a1 *v57; // rax
int v58; // eax
jfieldID FieldId; // rax
jobject v61; // [rsp+30h] [rbp-18h]
jobject v62; // [rsp+30h] [rbp-18h]
jobject v63; // [rsp+30h] [rbp-18h]
*a1 = off_1801DCA48;
*a1 = off_1801DCA38;
sub_180102590(a1 + 176);
qword_1802D72F0 = sub_180171C00();
*(a1 + 168) = a2;
sub_180171C00();
gForgeVersion = getForgeVersion();
if ( gForgeVersion == 13 )
dword_1802D7310 = 3;
else
dword_1802D7310 = 1;
if ( gForgeVersion == 13 )
{
v2 = VapeClassLoader();
*(a1 + 200) = VapeClassFinder(v2, "Lcpw/mods/fml/common/eventhandler/Event;");
v3 = VapeClassLoader();
*(a1 + 208) = VapeClassFinder(v3, "Lcpw/mods/fml/common/eventhandler/ListenerList;");
v4 = VapeClassLoader();
*(a1 + 216) = VapeClassFinder(v4, "Lcpw/mods/fml/common/eventhandler/EventPriority;");
v5 = VapeClassLoader();
*(a1 + 272) = VapeClassFinder(v5, "Lcpw/mods/fml/common/eventhandler/ListenerList$ListenerListInst;");
v6 = VapeClassLoader();
*(a1 + 224) = VapeClassFinder(v6, "Lcpw/mods/fml/common/eventhandler/IEventListener;");
v7 = VapeClassLoader();
*(a1 + 240) = sub_180026910(v7, *(a1 + 200), "getListenerList", "()Lcpw/mods/fml/common/eventhandler/ListenerList;");
v8 = VapeClassLoader();
*(a1 + 152) = sub_180026910(v8, *(a1 + 200), "setCanceled", "(Z)V");
v9 = VapeClassLoader();
*(a1 + 248) = sub_180026910(
v9,
*(a1 + 208),
"register",
"(ILcpw/mods/fml/common/eventhandler/EventPriority;Lcpw/mods/fml/common/eventhandler/IEventListener;)V");
v10 = VapeClassLoader();
*(a1 + 256) = sub_180026910(v10, *(a1 + 208), "unregister", "(ILcpw/mods/fml/common/eventhandler/IEventListener;)V");
v11 = VapeClassLoader();
*(a1 + 288) = sub_180026910(
v11,
*(a1 + 208),
"getListeners",
"(I)[Lcpw/mods/fml/common/eventhandler/IEventListener;");
v12 = VapeClassLoader();
*(a1 + 232) = sub_180026F90(v12, *(a1 + 216), "HIGHEST", "Lcpw/mods/fml/common/eventhandler/EventPriority;", 0LL);
}
else
{
if ( gForgeVersion < 26 )
{
v22 = VapeClassLoader();
*(a1 + 200) = VapeClassFinder(v22, "Lnet/minecraftforge/fml/common/eventhandler/Event;");
v23 = VapeClassLoader();
*(a1 + 208) = VapeClassFinder(v23, "Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
v24 = VapeClassLoader();
*(a1 + 216) = VapeClassFinder(v24, "Lnet/minecraftforge/fml/common/eventhandler/EventPriority;");
v25 = VapeClassLoader();
*(a1 + 272) = VapeClassFinder(v25, "Lnet/minecraftforge/fml/common/eventhandler/ListenerList$ListenerListInst;");
*(a1 + 240) = JNI_GetMethodID(
a2,
*(a1 + 200),
"getListenerList",
"()Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
v26 = VapeClassLoader();
*(a1 + 248) = sub_180026910(
v26,
*(a1 + 208),
"register",
"(ILnet/minecraftforge/fml/common/eventhandler/EventPriority;Lnet/minecraftforge/fml/common/eventha"
"ndler/IEventListener;)V");
v27 = VapeClassLoader();
*(a1 + 256) = sub_180026910(
v27,
*(a1 + 208),
"unregister",
"(ILnet/minecraftforge/fml/common/eventhandler/IEventListener;)V");
v28 = VapeClassLoader();
*(a1 + 288) = sub_180026910(
v28,
*(a1 + 208),
"getListeners",
"(I)[Lnet/minecraftforge/fml/common/eventhandler/IEventListener;");
v29 = VapeClassLoader();
v21 = sub_180026F90(
v29,
*(a1 + 216),
"HIGHEST",
"Lnet/minecraftforge/fml/common/eventhandler/EventPriority;",
0LL);
}
else
{
v13 = VapeClassLoader();
*(a1 + 200) = VapeClassFinder(v13, "Lnet/minecraftforge/eventbus/api/Event;");
v14 = VapeClassLoader();
*(a1 + 208) = VapeClassFinder(v14, "Lnet/minecraftforge/eventbus/ListenerList;");
v15 = VapeClassLoader();
*(a1 + 216) = VapeClassFinder(v15, "Lnet/minecraftforge/eventbus/api/EventPriority;");
v16 = VapeClassLoader();
*(a1 + 272) = VapeClassFinder(v16, "Lnet/minecraftforge/eventbus/ListenerList$ListenerListInst;");
*(a1 + 240) = JNI_GetMethodID(a2, *(a1 + 200), "getListenerList", "()Lnet/minecraftforge/eventbus/ListenerList;");
v17 = VapeClassLoader();
*(a1 + 248) = sub_180026910(
v17,
*(a1 + 208),
"register",
"(ILnet/minecraftforge/eventbus/api/EventPriority;Lnet/minecraftforge/eventbus/api/IEventListener;)V");
v18 = VapeClassLoader();
*(a1 + 256) = sub_180026910(
v18,
*(a1 + 208),
"unregister",
"(ILnet/minecraftforge/eventbus/api/IEventListener;)V");
v19 = VapeClassLoader();
*(a1 + 288) = sub_180026910(
v19,
*(a1 + 208),
"getListeners",
"(I)[Lnet/minecraftforge/eventbus/api/IEventListener;");
v20 = VapeClassLoader();
v21 = sub_180026F90(v20, *(a1 + 216), "HIGHEST", "Lnet/minecraftforge/eventbus/api/EventPriority;", 0LL);
}
*(a1 + 232) = v21;
*(a1 + 152) = JNI_GetMethodID(a2, *(a1 + 200), "setCanceled", "(Z)V");
}
if ( gForgeVersion < 26 )
{
v30 = VapeClassLoader();
*(a1 + 8) = vapeClassLoader(v30);
}
if ( gForgeVersion < 35 )
{
v33 = VapeClassLoader();
*(a1 + 32) = vapeClassLoader(v33);
}
else
{
v31 = VapeClassLoader();
*(a1 + 32) = vapeClassLoader(v31);
v32 = VapeClassLoader();
*(a1 + 72) = vapeClassLoader(v32);
}
v34 = VapeClassLoader();
*(a1 + 16) = vapeClassLoader(v34);
v35 = VapeClassLoader();
*(a1 + 24) = vapeClassLoader(v35);
v36 = VapeClassLoader();
*(a1 + 64) = vapeClassLoader(v36);
v37 = VapeClassLoader();
*(a1 + 80) = vapeClassLoader(v37);
v38 = VapeClassLoader();
*(a1 + 88) = vapeClassLoader(v38);
v39 = VapeClassLoader();
*(a1 + 96) = vapeClassLoader(v39);
*(a1 + 104) = JNI_GetFieldId(
a2,
*(a1 + 80),
"type",
"Lnet/minecraftforge/client/event/RenderGameOverlayEvent$ElementType;");
*(a1 + 112) = JNI_GetStaticFieldID(a2);
if ( gForgeVersion < 26 )
fieldID = JNI_GetFieldId(a2, *(a1 + 16), "entityLiving", "Lnet/minecraft/entity/EntityLivingBase;");
else
fieldID = JNI_GetFieldId(a2, *(a1 + 16), "entityLiving", "Lnet/minecraft/entity/LivingEntity;");
if ( gForgeVersion == 13 )
{
v40 = VapeClassLoader();
v61 = vapeClassLoader(v40);
v41 = VapeClassLoader();
*(a1 + 48) = vapeClassLoader(v41);
v42 = VapeClassLoader();
*(a1 + 40) = vapeClassLoader(v42);
v43 = VapeClassLoader();
*(a1 + 56) = vapeClassLoader(v43);
v44 = VapeClassLoader();
*(a1 + 120) = vapeClassLoader(v44);
*(a1 + 136) = JNI_GetFieldId(a2, v61, "phase", "Lcpw/mods/fml/common/gameevent/TickEvent$Phase;");
*(a1 + 144) = JNI_GetStaticFieldID(a2);
v45 = VapeClassLoader();
*(a1 + 280) = sub_180026F90(
v45,
*(a1 + 208),
"lists",
"[Lcpw/mods/fml/common/eventhandler/ListenerList$ListenerListInst;",
0LL);
}
else
{
if ( gForgeVersion < 26 )
{
v53 = VapeClassLoader();
v63 = VapeClassFinder(v53, "net/minecraftforge/fml/common/gameevent/TickEvent");
v54 = VapeClassLoader();
*(a1 + 48) = VapeClassFinder(v54, "net/minecraftforge/fml/common/gameevent/TickEvent$RenderTickEvent");
v55 = VapeClassLoader();
*(a1 + 40) = VapeClassFinder(v55, "net/minecraftforge/fml/common/gameevent/TickEvent$PlayerTickEvent");
v56 = VapeClassLoader();
*(a1 + 56) = VapeClassFinder(v56, "net/minecraftforge/fml/common/gameevent/TickEvent$ClientTickEvent");
v57 = VapeClassLoader();
*(a1 + 120) = vapeClassLoader(v57);
*(a1 + 136) = JNI_GetFieldId(a2, v63, "phase", "Lnet/minecraftforge/fml/common/gameevent/TickEvent$Phase;");
*(a1 + 144) = JNI_GetStaticFieldID(a2);
v58 = VapeClassLoader();
v52 = sub_180026F90(
v58,
*(a1 + 208),
"lists",
"[Lnet/minecraftforge/fml/common/eventhandler/ListenerList$ListenerListInst;",
0LL);
}
else
{
v46 = VapeClassLoader();
v62 = VapeClassFinder(v46, "net/minecraftforge/event/TickEvent");
v47 = VapeClassLoader();
*(a1 + 48) = VapeClassFinder(v47, "net/minecraftforge/event/TickEvent$RenderTickEvent");
v48 = VapeClassLoader();
*(a1 + 40) = VapeClassFinder(v48, "net/minecraftforge/event/TickEvent$PlayerTickEvent");
v49 = VapeClassLoader();
*(a1 + 56) = VapeClassFinder(v49, "net/minecraftforge/event/TickEvent$ClientTickEvent");
v50 = VapeClassLoader();
*(a1 + 120) = vapeClassLoader(v50);
*(a1 + 136) = JNI_GetFieldId(a2, v62, "phase", "Lnet/minecraftforge/event/TickEvent$Phase;");
*(a1 + 144) = JNI_GetStaticFieldID(a2);
v51 = VapeClassLoader();
v52 = sub_180026F90(
v51,
*(a1 + 208),
"lists",
"[Lnet/minecraftforge/eventbus/ListenerList$ListenerListInst;",
0LL);
}
*(a1 + 280) = v52;
}
if ( gForgeVersion < 26 )
FieldId = JNI_GetFieldId(a2, *(a1 + 40), "player", "Lnet/minecraft/entity/player/EntityPlayer;");
else
FieldId = JNI_GetFieldId(a2, *(a1 + 40), "player", "Lnet/minecraft/entity/player/PlayerEntity;");
*(a1 + 128) = FieldId;
return a1;
}
EventHandler
EventHandler由Invoke调用而来,可以发现他把第一个jobject解引用了,一般情况下,这是非法操作,但是Vape通过自己布局Object,使得类偏移为8的地方放置了Dispatcher。
__int64 __fastcall Java_p000_C000a_invoke(JNIEnv *a1, __int64 a2, jobject Event)
{
__int64 result; // rax
__int64 (__fastcall **v4)(JNIEnv *, jobject); // rax
unsigned __int64 v5; // [rsp+28h] [rbp-20h] BYREF
v5 = *(deRef(Event) + 8);
result = BstSearch::contains(&bst_Tree, &v5);
if ( result )
{
v4 = Bst::FindAndIns(&bst_Tree, &v5);
return (*v4)(a1, Event);
}
return result;
}
典型的事件分发流程。
主功能
Vape Lite的所有功能的操作都在主程序,主程序与StubDll通信然后StubDll进行相应的操作来做到,另外,Vape Lite还支持非Forge客户端的劫持,这个笔者有时间会继续深入研究。
检测 & 防止
检测方案
防止方案
相关附件
Vape V4
附件包括vape_v4.exe(主程序),vape_v4.dll(Dumped Stub)与 vape.jar (通过DefineClass动态注册的客户端核心)。
下载: https://sts.lanzoue.com/i4fHf312btif 密码: a4o4
仅供学习参考使用,请在下载后24h内自行删除。