Skip to content

Instantly share code, notes, and snippets.

@xerpi
Last active November 11, 2016 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xerpi/ba032cf937f54d4254716e7d78a9b88c to your computer and use it in GitHub Desktop.
Save xerpi/ba032cf937f54d4254716e7d78a9b88c to your computer and use it in GitHub Desktop.
/*
* wikinidparser by xerpi
* Usage:
* - hxpipe SceFoo > SceFoo_piped
* - ./wikinidparser SceFoo_piped
*/
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdint>
#include <list>
typedef uint32_t vita_nid_t;
struct vita_function_t {
std::string name;
vita_nid_t nid;
};
struct vita_library_t {
std::string name;
vita_nid_t nid;
bool visibility;
std::list<vita_function_t> functions;
};
struct vita_module_t {
std::string name;
vita_nid_t nid;
bool privilege;
std::list<vita_library_t> libraries;
};
static std::string rtrim(std::string s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
static void skip_lines(std::istringstream &is, int n)
{
std::string line;
for (int i = 1; i < n; i++) {
std::getline(is, line);
}
}
int main(int argc, char *argv[])
{
vita_module_t module;
if (argc < 2) {
std::cout << "Usage: wikinidparser <html filename>.\n";
exit(EXIT_FAILURE);
}
std::ifstream in(argv[1], std::ios::in | std::ios::binary);
if (!in) {
std::cout << "File " << argv[1] << " not found!\n";
exit(EXIT_FAILURE);
}
std::string contents;
in.seekg(0, std::ios::end);
contents.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
in.close();
std::istringstream is(contents);
bool found_module = false;
bool found_libs = false;
std::string line;
std::string tmp;
while (std::getline(is, line)) {
/* Module */
if (line.compare("Aid CDATA Known_NIDs") == 0 && !found_module) {
std::string module_name;
bool kernel;
uint32_t nid;
skip_lines(is, 35);
std::getline(is, tmp);
module_name = rtrim(tmp.substr(tmp.find("Sce")));
skip_lines(is, 8);
std::getline(is, tmp);
kernel = tmp.find("Kernel") != std::string::npos;
skip_lines(is, 4);
std::getline(is, tmp);
nid = std::stoul(tmp.substr(tmp.find("0x")), nullptr, 16);
module.name = module_name;
module.nid = nid;
module.privilege = kernel;
found_module = true;
} else if (line.compare("Aid CDATA Known_NIDs_2") == 0 && !found_libs) { /* Lib */
skip_lines(is, 37);
while (true) {
std::string lib_name;
bool kernel;
uint32_t nid;
std::size_t found;
std::getline(is, line);
if (line.find("Atitle CDATA") == std::string::npos)
break;
skip_lines(is, 2);
std::getline(is, tmp);
found = tmp.find("Sce");
if (found == std::string::npos)
break;
lib_name = rtrim(tmp.substr(found));
skip_lines(is, 10);
std::getline(is, tmp);
kernel = tmp.find("Kernel") != std::string::npos;
skip_lines(is, 4);
std::getline(is, tmp);
nid = std::stoul(tmp.substr(tmp.find("0x")), nullptr, 16);
vita_library_t library;
library.name = lib_name;
library.nid = nid;
library.visibility = kernel;
module.libraries.push_back(library);
skip_lines(is, 11);
}
found_libs = true;
}
/* Functions */
if (line.find("Aid CDATA Sce") != std::string::npos && found_module && found_libs) {
std::string library;
size_t found;
library = rtrim(line.substr(line.find("Sce")));
skip_lines(is, 11);
while (1) {
std::string func_name;
uint32_t nid;
std::getline(is, tmp);
found = tmp.find("sce");
if (found == std::string::npos)
break;
func_name = rtrim(tmp.substr(found));
skip_lines(is, 23);
std::getline(is, tmp);
nid = std::stoul(tmp.substr(tmp.find("0x")), nullptr, 16);
vita_function_t function;
function.name = func_name;
function.nid = nid;
std::list<vita_library_t>::iterator lib_it;
for (lib_it = module.libraries.begin(); lib_it != module.libraries.end(); lib_it++) {
if (lib_it->name.compare(library) == 0)
break;
}
if (lib_it != module.libraries.end())
lib_it->functions.push_back(function);
skip_lines(is, 7);
}
}
}
std::cout << "{" << std::endl;
std::cout << "\t\"" << module.name << "\": {" << std::endl;
std::cout << "\t\t\"" << "modules" << "\": {" << std::endl;
std::list<vita_library_t>::iterator lib_it;
for (lib_it = module.libraries.begin(); lib_it != module.libraries.end(); lib_it++) {
std::cout << "\t\t\t\"" << lib_it->name << "\": {" << std::endl;
std::cout << "\t\t\t\t\"" << "functions" << "\": {" << std::endl;
std::list<vita_function_t>::iterator func_it;
for (func_it = lib_it->functions.begin(); func_it != lib_it->functions.end(); func_it++) {
std::cout << "\t\t\t\t\t\"" << func_it->name << "\": " << func_it->nid;
if (func_it != std::prev(lib_it->functions.end()))
std::cout << ",";
std::cout << std::endl;
}
std::cout << "\t\t\t\t}," << std::endl;
std::cout << "\t\t\t\t\"kernel\": " << (lib_it->visibility ? "true" : "false") << "," << std::endl;
std::cout << "\t\t\t\t\"nid\": " << lib_it->nid << std::endl;
std::cout << "\t\t\t}";
if (lib_it != std::prev(module.libraries.end()))
std::cout << ",";
std::cout << std::endl;
}
std::cout << "\t\t}," << std::endl;
std::cout << "\t\t\"nid\": " << module.nid << std::endl;
std::cout << "\t}" << std::endl;
std::cout << "}" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment