Skip to content

Instantly share code, notes, and snippets.

@ar1a
Last active July 11, 2016 07:50
Show Gist options
  • Save ar1a/00fa7182ea826581554ad8f3013b428e to your computer and use it in GitHub Desktop.
Save ar1a/00fa7182ea826581554ad8f3013b428e to your computer and use it in GitHub Desktop.
Source engine interfaces using the libraries linked list instead of bruteforcing
// modified from original shit Altimor posted
class Dynamic_interface
{
struct Interface_linked_list {
void* (*func)();
const char* name;
Interface_linked_list* next;
};
Interface_linked_list* interface_list;
public:
Dynamic_interface(const std::string& module)
{
void* create_interface =
dlsym(dlopen(module.c_str(), RTLD_NOW), "CreateInterface");
uintptr_t jmp_instr = (uintptr_t)(create_interface) + 4;
// READING IT AS A INTPTR_T INSTEAD OF SIZE_T IS A MUST!
// RELATIVE JUMPS CAN BE NEGATIVE TOO!
uintptr_t jmp_target = jmp_instr + *(intptr_t*)(jmp_instr + 1) + 5;
interface_list = **(Interface_linked_list***)(jmp_target + 11);
printf("%s interface ptr: 0x%X\n", module.c_str(),
(uintptr_t)interface_list);
}
template <typename T = void>
T* get(const std::string& intf_name)
{
for (auto* list_ptr = interface_list; list_ptr; list_ptr = list_ptr->next) {
if (std::string(list_ptr->name).substr(0, intf_name.length()) ==
intf_name) {
try {
int version = std::stoi(list_ptr->name + intf_name.length());
auto* result = list_ptr->func();
printf("%s v%.3d: 0x%X\n", intf_name.c_str(), version,
(uintptr_t)result);
return (T*)result;
} catch (std::invalid_argument& e) {
// no conversion could be made
}
}
}
printf("ERROR! Couldn't find %s\n", intf_name.c_str());
}
template <typename T = void>
T* get_raw(const std::string& intf_name)
{
for (auto* list_ptr = interface_list; list_ptr; list_ptr = list_ptr->next) {
if (intf_name == list_ptr->name) {
auto* result = list_ptr->func();
printf("%s v%.3d: 0x%X\n",
intf_name.substr(0, intf_name.length() - 3).c_str(),
std::stoi(intf_name.substr(intf_name.length() - 3)),
(uintptr_t)result);
return (T*)result;
}
}
printf("ERROR! Couldn't find %s\n", intf_name.c_str());
}
std::string dump_all()
{
std::stringstream ss;
for (auto* list_ptr = interface_list; list_ptr; list_ptr = list_ptr->next) {
ss << list_ptr->name << std::endl;
}
return std::move(ss.str());
}
return std::move(ss.str());
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment