Skip to content

Commit

Permalink
implement in C++
Browse files Browse the repository at this point in the history
  • Loading branch information
4z0t authored and Garanas committed Nov 11, 2024
1 parent 666951d commit bac292a
Showing 1 changed file with 153 additions and 125 deletions.
278 changes: 153 additions & 125 deletions section/GetTableSize.cpp
Original file line number Diff line number Diff line change
@@ -1,109 +1,133 @@
void GetTableSize()
#include "include/LuaAPI.h"
namespace lua
{
struct TObject
{
int tt;
void *value;
};

struct Node
{
TObject i_key;
TObject i_val;
Node *next;
};

struct Table
{
/* lua::GCObject*/ void *next;
uint8_t tt;
uint8_t marked;
uint16_t gap;
uint8_t flags;
uint8_t lsizenode;
// padding byte
// padding byte
Table *metatable;
TObject *array;
lua::Node *node;
lua::Node *firstfree;
/*lua::GCObject*/ void *gclist;
int sizearray;
};

} // namespace lua

VALIDATE_SIZE(lua::Table, 0x24);

int lua_tablesize(lua_State *L)
{
asm(
"PushNumber = 0x0090CD40;"
"MOV EAX,[ESI+0xC];"
"CMP EAX,[ESI+0x8];"
"JAE Err;"
"CMP DWORD PTR [EAX],0x5;"
"JNE Err;"
"MOV EAX,[EAX+0x4];"
"XOR EBX,EBX;"
"MOV CL,[EAX+0x9];"
"TEST CL,CL;"
"JZ GTS_L2;"
"MOV EDX,1;"
"SHL EDX,CL;"
"MOV ECX,[EAX+0x14];"
"GTS_L3:;"
"CMP DWORD PTR [ECX+0x8],0x0;"
"JE GTS_L4;"
"ADD EBX,0x1;"
"GTS_L4:;"
"ADD ECX,0x14;"
"DEC EDX;"
"JNZ GTS_L3;"
"GTS_L2:;"
"MOV EDX,[EAX+0x20];"
"TEST EDX,EDX;"
"JZ GTS_L7;"
"MOV ECX,[EAX+0x10];"
"GTS_L5:;"
"CMP DWORD PTR [ECX],0x0;"
"JE GTS_L6;"
"ADD EBX,0x1;"
"GTS_L6:;"
"ADD ECX,0x8;"
"DEC EDX;"
"JNZ GTS_L5;"
"GTS_L7:;"
"CVTSI2SS XMM0,EBX;"
"SUB ESP,0x4;"
"MOVSS [ESP],XMM0;"
"PUSH ESI;"
"CALL PushNumber;"
"ADD ESP,0x8;"
"MOV EAX,0x1;"
"RET;"
"Err:;"
"SUB ESP,0x4;"
"XORPS XMM0, XMM0;"
"MOVSS [ESP],XMM0;"
"PUSH ESI;"
"CALL PushNumber;"
"ADD ESP,0x8;"
"MOV EAX,0x1;"
"RET;"
);
int size = 0;
auto base = GetField<lua::TObject *>(L, 0xC);
auto top = GetField<lua::TObject *>(L, 0x8);
if (base >= top || base->tt != LUA_TTABLE)
{
lua_pushnumber(L, size);
return 1;
}

auto table = (lua::Table *)base->value;
uint8_t lsizenode = table->lsizenode;
if (lsizenode)
{
uint32_t num_nodes = 1 << lsizenode;
auto node = table->node;
do
{
if (node->i_val.tt)
++size;
++node;
--num_nodes;
} while (num_nodes);
}
int sizearray = table->sizearray;
if (sizearray)
{
auto array = table->array;
do
{
if (array->tt)
++size;
++array;
--sizearray;
} while (sizearray);
}

lua_pushnumber(L, size);
return 1;
}

void IsTableEmpty()
int lua_tableempty(lua_State *L)
{
asm(
"MOV EAX,[ESI+0xC];"
"CMP EAX,[ESI+0x8];"
"JAE ITE_L72;"
"CMP DWORD PTR [EAX],0x5;"
"JNE ITE_L72;"
"MOV EAX,[EAX+0x4];"
"MOV CL,[EAX+0x9];"
"TEST CL,CL;"
"JZ ITE_L22;"
"MOV EDX,1;"
"SHL EDX,CL;"
"MOV ECX,[EAX+0x14];"
"ITE_L32:;"
"CMP DWORD PTR [ECX+0x8],0x0;"
"JNE ITE_L62;"
"ADD ECX,0x14;"
"DEC EDX;"
"JNZ ITE_L32;"
"ITE_L22:;"
"MOV EDX,[EAX+0x20];"
"TEST EDX,EDX;"
"JZ ITE_L72;"
"MOV ECX,[EAX+0x10];"
"ITE_L5:;"
"CMP DWORD PTR [ECX],0x0;"
"JNE ITE_L62;"
"ADD ECX,0x8;"
"DEC EDX;"
"JNZ ITE_L5;"
"ITE_L72:;"
"PUSH 0x1;"
"JMP ITE_L12;"
"ITE_L62:;"
"PUSH 0x0;"
"ITE_L12:;"
"PUSH ESI;"
"CALL 0x0090CF80;" //PushBool
"ADD ESP,0x8;"
"MOV EAX,0x1;"
);
auto base = GetField<lua::TObject *>(L, 0xC);
auto top = GetField<lua::TObject *>(L, 0x8);
if (base >= top || base->tt != LUA_TTABLE)
{
lua_pushboolean(L, true);
return 1;
}

auto table = (lua::Table *)base->value;
constexpr auto has_nodes = [](lua::Table *t)
{
uint8_t lsizenode = t->lsizenode;
if (!lsizenode)
return false;

uint32_t num_nodes = 1 << lsizenode;
auto node = t->node;
while (node->i_val.tt == LUA_TNIL)
{
++node;
if (!--num_nodes)
return false;
}
return true;
};

constexpr auto has_array = [](lua::Table *t)
{
int sizearray = t->sizearray;
if (!sizearray)
return false;

auto array = t->array;
while (array->tt == LUA_TNIL)
{
++array;
if (!--sizearray)
return false;
}
return true;
};

lua_pushboolean(L, !(has_nodes(table) || has_array(table)));
return 1;
}

#include "include/LuaAPI.h"
int TableClone(lua_State* L)
int TableClone(lua_State *L)
{
LuaObject obj{L->LuaState, 1};
LuaObject cloned{};
Expand All @@ -119,32 +143,36 @@ int TableClone(lua_State* L)
// UI_Lua reprsl({table.unpack2({1,2,3,4},-1000)})
// UI_Lua reprsl({table.unpack2({1,2,3,4},0, 1000000)}) //stack overflow

int lua_unpack(lua_State *l) {
luaL_checktype(l, 1, LUA_TTABLE);
const int n = lua_getn(l, 1);
const int start_i = luaL_optnumber(l, 2, 1);
const int end_i = luaL_optnumber(l, 3, n);
if(start_i > end_i) return 0;

const int n_stack = end_i - start_i + 1;
luaL_checkstack(l, n_stack, "too many results to unpack");
for (int i = start_i; i <= end_i; i++) {
lua_rawgeti(l, 1, i);
}
return n_stack;
int lua_unpack(lua_State *l)
{
luaL_checktype(l, 1, LUA_TTABLE);
const int n = lua_getn(l, 1);
const int start_i = luaL_optnumber(l, 2, 1);
const int end_i = luaL_optnumber(l, 3, n);
if (start_i > end_i)
return 0;

const int n_stack = end_i - start_i + 1;
luaL_checkstack(l, n_stack, "too many results to unpack");
for (int i = start_i; i <= end_i; i++)
{
lua_rawgeti(l, 1, i);
}
return n_stack;
}

int RegTableFuncsDesc[] = {"getsize2",&GetTableSize, "empty2", &IsTableEmpty,
"getn2", 0x00927C20, "clone", &TableClone,
"unpack", &lua_unpack, 0, 0};

void RegTableFuncs() {
asm("CALL 0x0090DE00;"
"MOV DWORD PTR [ESP+0x8],%[RegTableFuncsDesc];"
"MOV DWORD PTR [ESP+0xC],0x0;"
"CALL 0x0090DE00;"
"JMP 0x009283B6;"
:
: [RegTableFuncsDesc] "i"(RegTableFuncsDesc)
:);
int RegTableFuncsDesc[] = {"getsize2", &lua_tablesize, "empty2", &lua_tableempty,
"getn2", 0x00927C20, "clone", &TableClone,
"unpack", &lua_unpack, 0, 0};

void RegTableFuncs()
{
asm("CALL 0x0090DE00;"
"MOV DWORD PTR [ESP+0x8],%[RegTableFuncsDesc];"
"MOV DWORD PTR [ESP+0xC],0x0;"
"CALL 0x0090DE00;"
"JMP 0x009283B6;"
:
: [RegTableFuncsDesc] "i"(RegTableFuncsDesc)
:);
}

0 comments on commit bac292a

Please sign in to comment.