#include #include #include #include #include #include #include #include #define BUFFER_SIZE 1024 void Assert(bool cond, const char* desc) { if (!cond) { std::cout << desc << std::endl; ExitProcess(0); } } struct MyModuleInfo { intptr_t BaseOfDll; intptr_t EntryPoint; std::string ModuleName; }; std::map ConstructModuleList() { std::map result; HANDLE hProc = GetCurrentProcess(); HMODULE* hMods = new HMODULE[1024]; TCHAR* szModName = new TCHAR[MAX_PATH]; MODULEINFO infoMod; DWORD cbNeeded; DWORD nameLen; if (EnumProcessModules(hProc, hMods, sizeof(HMODULE) * 1024, &cbNeeded)) { for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i) { MyModuleInfo data; nameLen = GetModuleBaseName(hProc, hMods[i], szModName, MAX_PATH); if (nameLen) { data.ModuleName.resize(nameLen); memcpy(data.ModuleName.data(), szModName, nameLen * sizeof(TCHAR)); } else data.ModuleName = ""; if (GetModuleInformation(hProc, hMods[i], &infoMod, sizeof(infoMod))) { data.BaseOfDll = reinterpret_cast(infoMod.lpBaseOfDll); data.EntryPoint = reinterpret_cast(infoMod.EntryPoint); } else { data.BaseOfDll = 0; data.EntryPoint = 0; } result.emplace(data.BaseOfDll, data); } } delete[] hMods; delete[] szModName; return result; } void PrintVTable(std::map& modules, CKDWORD* pCls, size_t vtable_len, char indent) { if (pCls == nullptr) { fputc('\n', stdout); return; } CKDWORD* vtable = *(reinterpret_cast(pCls)); for (size_t i = 0; i < vtable_len; ++i) { intptr_t addr = vtable[i]; const auto& it = modules.lower_bound(addr); if (it != modules.end() && it != modules.begin()) { const auto& itt = std::prev(it); fprintf(stdout, "%s::", itt->second.ModuleName.c_str()); addr = addr - itt->second.BaseOfDll; if (itt->second.ModuleName == "CK2_3D.dll") addr += 0x10000000u; else if (itt->second.ModuleName == "CK2.dll") addr += 0x24000000u; } fprintf(stdout, "%08X%c", addr, indent); } fputc('\n', stdout); } int main() { Assert(LoadLibrary("CK2.dll"), "Error loading CK2.dll"); Assert(!CKStartUp(), "CKStartUp Error"); std::string sharedStorage; sharedStorage.resize(BUFFER_SIZE); std::filesystem::path rootPath, rePath, magPath, plgPath, bbPath; GetModuleFileName(NULL, sharedStorage.data(), BUFFER_SIZE); rootPath = sharedStorage; rootPath = rootPath.parent_path(); rePath = rootPath / "RenderEngines"; magPath = rootPath / "Managers"; plgPath = rootPath / "Plugins"; bbPath = rootPath / "BuildingBlocks"; CKPluginManager* pluginManager = CKGetPluginManager(); int k = 0; k += pluginManager->ParsePlugins((char*)rePath.string().c_str()); k += pluginManager->ParsePlugins((char*)magPath.string().c_str()); k += pluginManager->ParsePlugins((char*)plgPath.string().c_str()); k += pluginManager->ParsePlugins((char*)bbPath.string().c_str()); std::cout << "Total loaded modules count: " << k << std::endl; CKContext* ctx = NULL; Assert(!CKCreateContext(&ctx, NULL, 0), "Fail to execute CKCreateContext()"); std::cout << "Press any key to run..." << std::endl; system("pause"); // print CKObject vtable //static std::vector cls{ // CKCID_OBJECT, // CKCID_PARAMETERIN, // CKCID_PARAMETEROPERATION, // CKCID_STATE, // CKCID_BEHAVIORLINK, // CKCID_BEHAVIOR, // CKCID_BEHAVIORIO, // CKCID_RENDERCONTEXT, // CKCID_KINEMATICCHAIN, // CKCID_SCENEOBJECT, // CKCID_OBJECTANIMATION, // CKCID_ANIMATION, // CKCID_KEYEDANIMATION, // CKCID_BEOBJECT, // CKCID_DATAARRAY, // CKCID_SCENE, // CKCID_LEVEL, // CKCID_PLACE, // CKCID_GROUP, // CKCID_SOUND, // CKCID_WAVESOUND, // CKCID_MIDISOUND, // CKCID_MATERIAL, // CKCID_TEXTURE, // CKCID_MESH, // CKCID_PATCHMESH, // CKCID_RENDEROBJECT, // CKCID_2DENTITY, // CKCID_SPRITE, // CKCID_SPRITETEXT, // CKCID_3DENTITY, // CKCID_GRID, // CKCID_CURVEPOINT, // CKCID_SPRITE3D, // CKCID_CURVE, // CKCID_CAMERA, // CKCID_TARGETCAMERA, // CKCID_LIGHT, // CKCID_TARGETLIGHT, // CKCID_CHARACTER, // CKCID_3DOBJECT, // CKCID_BODYPART, // CKCID_PARAMETER, // CKCID_PARAMETERLOCAL, // CKCID_PARAMETERVARIABLE, // CKCID_PARAMETEROUT, // CKCID_INTERFACEOBJECTMANAGER, // CKCID_CRITICALSECTION, // CKCID_LAYER, // CKCID_PROGRESSIVEMESH, // CKCID_SYNCHRO //}; //static std::vector clsname{ // "CKCID_OBJECT", // "CKCID_PARAMETERIN", // "CKCID_PARAMETEROPERATION", // "CKCID_STATE", // "CKCID_BEHAVIORLINK", // "CKCID_BEHAVIOR", // "CKCID_BEHAVIORIO", // "CKCID_RENDERCONTEXT", // "CKCID_KINEMATICCHAIN", // "CKCID_SCENEOBJECT", // "CKCID_OBJECTANIMATION", // "CKCID_ANIMATION", // "CKCID_KEYEDANIMATION", // "CKCID_BEOBJECT", // "CKCID_DATAARRAY", // "CKCID_SCENE", // "CKCID_LEVEL", // "CKCID_PLACE", // "CKCID_GROUP", // "CKCID_SOUND", // "CKCID_WAVESOUND", // "CKCID_MIDISOUND", // "CKCID_MATERIAL", // "CKCID_TEXTURE", // "CKCID_MESH", // "CKCID_PATCHMESH", // "CKCID_RENDEROBJECT", // "CKCID_2DENTITY", // "CKCID_SPRITE", // "CKCID_SPRITETEXT", // "CKCID_3DENTITY", // "CKCID_GRID", // "CKCID_CURVEPOINT", // "CKCID_SPRITE3D", // "CKCID_CURVE", // "CKCID_CAMERA", // "CKCID_TARGETCAMERA", // "CKCID_LIGHT", // "CKCID_TARGETLIGHT", // "CKCID_CHARACTER", // "CKCID_3DOBJECT", // "CKCID_BODYPART", // "CKCID_PARAMETER", // "CKCID_PARAMETERLOCAL", // "CKCID_PARAMETERVARIABLE", // "CKCID_PARAMETEROUT", // "CKCID_INTERFACEOBJECTMANAGER", // "CKCID_CRITICALSECTION", // "CKCID_LAYER", // "CKCID_PROGRESSIVEMESH", // "CKCID_SYNCHRO" //}; // //auto moduleInfos = ConstructModuleList(); //fputs("Class Name,Class Id,Show(),IsHiddenByParent(),CanBeHide(),IsVisible(),~dtor(),GetClassID(),PreSave(),Save(),Load(),PostLoad(),PreDelete(),CheckPreDeletion(),CheckPostDeletion(),GetMemoryOccupation(),IsObjectUsed(),PrepareDependencies(),RemapDependencies(),Copy(),\n", stdout); //for (size_t j = 0; j < cls.size(); ++j) { // CK_CLASSID item = cls[j]; // const char* itemname = clsname[j]; // CKObject* obj = ctx->CreateObject(item, NULL, CK_OBJECTCREATION_NONAMECHECK, NULL); // fprintf(stdout, "%s,%d,", itemname, item); // PrintVTable(moduleInfos, reinterpret_cast(obj), 18); //} // print manager vtables auto moduleInfos = ConstructModuleList(); int count = ctx->GetManagerCount(); for (int i = 0; i < count; ++i) { CKBaseManager* mgr = ctx->GetManager(i); CKSTRING name = mgr->GetName(); CKGUID guid = mgr->GetGuid(); fprintf(stdout, "%s\t0x%08x, 0x%08x\t", name, guid.d1, guid.d2); PrintVTable(moduleInfos, reinterpret_cast(mgr), 30, '\t'); } // call reader //CKObjectArray* array = CreateCKObjectArray(); //Assert(!ctx->Load("Language.old.nmo", array, CK_LOAD_DEFAULT, NULL), "Fail to load CMO file"); // call saver //CKObjectArray* array = CreateCKObjectArray(); //CKObject* objs = ctx->CreateObject(CKCID_OBJECT, "fuck dassault", CK_OBJECTCREATION_NONAMECHECK, NULL); //array->AddIfNotHere(objs); //CKDependencies* dep = CKGetDefaultClassDependencies(CK_DEPENDENCIES_SAVE); //dep->m_Flags = CK_DEPENDENCIES_FULL; //Assert(!ctx->Save("result.cmo", array, 0xFFFFFFFF, dep, NULL), "Fail to save CMO file"); //DeleteCKObjectArray(array); std::cout << "Press any key to exit..." << std::endl; system("pause"); CKCloseContext(ctx); CKShutdown(); return 0; }