NoPref
Platinian
Hi. In trying to load BNM into the Standoff 2. In the new version devs put some protection. For example: locking System.Reflection and AppDomain in il2cpp_class_from_name, empty methods(il2cpp_image_get_class, il2cpp_image_*, il2cpp_method_get_param_name, and etc.). I'm stuck on il2cpp_domain_get_assemblies. As you can see from ida the method just doesn't make sense
But I found the GetAssemblies method in the AppDomain. Its pseudocode from ida:
For a test, I tried to hook it. My hook looks like this(I added System_Reflection_Assembly_o m_items[0] to struct Il2CppArray):
But the logs just don't make sense. It just spams a bunch of “Retrieved image for assembly: .????x”
The count of assemblies is 128
Can I even use this function to retrieve assemblies? If so, I don't understand how I should modify the BNM code to make it work. Would it even be appropriate to use BNM in this game?
C++:
__int64 __fastcall il2cpp_domain_get_assemblies(__int64 a1, _QWORD *a2)
{
__int64 result; // x0
result = 0LL;
*a2 = 0LL;
return result;
}
But I found the GetAssemblies method in the AppDomain. Its pseudocode from ida:
C++:
System_Reflection_Assembly_array *System_AppDomain__GetAssemblies_66651848(
System_AppDomain_o *this,
const MethodInfo *method)
{
return (System_Reflection_Assembly_array *)sub_200071C(this, 0LL);
}
C++:
__int64 sub_200071C()
{
__int64 *v0; // x19
__int64 v1; // x0
__int64 *v2; // x22
__int64 v3; // x20
int v4; // w8
__int64 v5; // t1
int v6; // w24
_QWORD *v7; // x21
v0 = sub_DE1EC4();
v1 = il2cpp_array_new_0(qword_45ED790, (v0[1] - *v0) >> 3);
v2 = (__int64 *)*v0;
v3 = v1;
if ( *v0 != v0[1] )
{
v4 = 0;
do
{
v5 = *v2++;
v6 = v4 + 1;
v7 = (_QWORD *)(v3 + 32 + 8LL * v4);
*v7 = sub_DE3B70(v5);
sub_DFBC2C(v7);
v4 = v6;
}
while ( v2 != (__int64 *)v0[1] );
}
return v3;
}
For a test, I tried to hook it. My hook looks like this(I added System_Reflection_Assembly_o m_items[0] to struct Il2CppArray):
C++:
BNM::IL2CPP::Il2CppArray* hooked_getassemblies(BNM::IL2CPP::Il2CppAppDomain* domain, const MethodInfo* method) {
auto domains = GetCurrentDomain();
uintptr_t symbol_address = g_il2cppELF.findSymbol("il2cpp_assembly_get_image");
using il2cpp_assembly_get_image_t = Il2CppImage*(*)(Il2CppAssembly*);
il2cpp_assembly_get_image_t il2cpp_assembly_get_image = reinterpret_cast<il2cpp_assembly_get_image_t>(symbol_address);
auto assemblies = original_getassemblies(domains, nullptr);
auto& assembly_items = assemblies->m_Items; // Referencing the items in the Il2CppArray
auto assembly_count = assemblies->max_length;
for (int i = 0; i < assembly_count; ++i) {
auto& assembly = (Il2CppAssembly*)assembly_items[i];
if (assembly) {
Il2CppImage* image = il2cpp_assembly_get_image(assembly);
if (image) {
KITTY_LOGI("Retrieved image for assembly: %s", image->name);
} else {
KITTY_LOGE("Failed to retrieve image for assembly at index %d", i);
}
}
}
return assemblies;
}
But the logs just don't make sense. It just spams a bunch of “Retrieved image for assembly: .????x”
The count of assemblies is 128
Can I even use this function to retrieve assemblies? If so, I don't understand how I should modify the BNM code to make it work. Would it even be appropriate to use BNM in this game?