Answer the question
In order to leave comments, you need to log in
How to optimize writing classes from memory?
The task was quite simple: the dll loaded into the process should read the class data stored there from the process memory and arrange them.
In this task, we do not have the opportunity to do this on the process side, everything must be done by a loadable dll, but in the process there is a function that can be called from a dll that returns a pointer to the first class in the list, with each class (except the last) containing a pointer to the next class. Here's what the class looks like:
class ClientClass
{
public:
const char* m_pNetworkName;
Table* m_pTable;
ClientClass* m_pNext;
};
Table
in turn, it is also a class and it contains structures that store information about class members - Prop
:struct Table
{
Prop* m_pProps; // Указатель на массив Prop'ов
int m_iProps; // количество Prop в Table
char* m_pNetTableName;
};
struct Prop
{
char* m_pVarName; // название члена класса
Table* m_pDataTable;
int m_Offset; // смещение указателя Prop относительно указателя Table
};
Prop
may be inside Table
, the information from which you also need to read. std::vector<std::string> base_classes;
static int class_level{ 0 };
void WriteAllOffsetsInLog()
{
// получаем указатель на первый класс
auto cl_class = Cl->GetFirstClass();
if (!cl_class)
return;
// сохраняем имена основных классов, чтобы не перечислять их члены в дочерних классах
while (cl_class)
{
auto table = cl_class->m_pTable;
if (table && table->m_iProps)
base_classes.push_back(table->m_pNetTableName);
cl_class = cl_class->m_pNext;
}
// снова находим первый класс
cl_class = Cl->GetFirstClass();
if (!cl_class)
return;
while (cl_class)
{
auto table = cl_class->m_pTable;
if (table && table->m_iProps)
{
class_level = 1;
// эта функция работает со структурами table и props
WriteClass(table, cl_class->m_pNetworkName);
}
cl_class = cl_class->m_pNext;
}
}
void WriteClass(Table* table, std::string name, int off = 0)
{
// добавляем табы в строчку в зависимости от того, насколько глубоко расположен класс в общем дереве
std::string tabtab = std::string();
for (int w = 0; w < class_level - 1; w++)
tabtab += " ";
std::string define_class { tabtab };
define_class += "class ";
define_class += name;
for (int i = 0; i < table->m_iProps; i++)
{
auto prop = table->m_pProps[i];
// перечисляем включённые классы справа от имени дочернего
if (prop.m_Offset == NULL && prop.m_pDataTable && prop.m_pDataTable->m_iProps && IsBaseClass(prop.m_pDataTable))
{
define_class += " : public ";
define_class += prop.m_pDataTable->m_pNetTableName;
}
}
if (off) // указатель класса смещён относительно материнского класса
{
define_class += " // ";
define_class += to16(off);
}
LOG(define_class);
LOG(tabtab + "{");
LOG(tabtab + "public:");
записываем члены класса
for (int i = 0; i < table->m_iProps; i++)
{
auto intabtab = tabtab + " ";
auto prop = table->m_pProps[i];
auto offset = to16(prop.m_Offset);
auto new_table = prop.m_pDataTable;
if (new_table) // член класса оказался классом и нужно вызвать функцию, которая запишет члены этого класса
{
if (!prop.m_Offset && IsBaseClass(new_table)) // оказалось, это не член класса, а включённый класс который будет расписан отдельно
continue;
if (new_table->m_iProps)
{
class_level++;
WriteClass(new_table, new_table->m_pNetTableName, prop.m_Offset);
class_level--;
}
}
else if (prop.m_Offset) // это просто переменная, запишем её смещение указателя
{
std::string log = intabtab;
log += "uintptr_t ";
log += prop.m_pVarName;
log += " = ";
log += offset;
log += ";";
LOG(log);
}
}
LOG(tabtab + "};");
LOG("");
if (class_level == 1)
LOG("");
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question