diff --git a/.gitignore b/.gitignore index d1f2eb5..6cf1274 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,12 @@ -.vs/ -.vscode/.cache/ -.vscode/compile_commands.json +# Xmake cache +.vscode/ +!.vscode/sftp.json +!.vscode/setting.json .xmake/ build/ -vsxmake*/ \ No newline at end of file +_vscode/ +vsxmake*/ +# MacOS Cache +.DS_Store + + diff --git a/.vscode/settings.json b/.vscode/settings.json index c98244c..1576d9e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,8 +8,8 @@ ], "packages": [ { - "name": "clua", - "description": "C + Lua API", + "name": "zlib", + "description": "c++ lib repo", "files": [ ".vscode/**", "**/*.json", @@ -42,7 +42,7 @@ "type": "sftp", "name": "sync", "description": "my tercent server for sync", - "dir": "/data/jupyter/sync/zlua", + "dir": "/data/jupyter/sync/zlib", "host": "124.221.147.27", "port": 22, "user": "root", diff --git a/.vscode/sftp.json b/.vscode/sftp.json index 563d355..8633274 100644 --- a/.vscode/sftp.json +++ b/.vscode/sftp.json @@ -5,7 +5,7 @@ "port": 22, "username": "root", "password": "@qq18770302583", - "remotePath": "/data/jupyter/sync/zlua", + "remotePath": "/data/jupyter/sync/zlib", "uploadOnSave": false, "useTempFile": false, "openSsh": false, diff --git a/src/clua/xmake.lua b/src/clua/xmake.lua deleted file mode 100644 index 9700b80..0000000 --- a/src/clua/xmake.lua +++ /dev/null @@ -1,46 +0,0 @@ - - - -target("clua") - set_kind("binary") - add_includedirs("src", {public = true}) - add_packages("lua","luasocket") - add_packages("protobuf-cpp","lua-protobuf") - - add_files("src/*.cpp","src/**/*.cpp") - - add_rules("protobuf.cpp") - add_files("proto/**.proto", {proto_rootdir = "src"}) - - add_headerfiles("src/*.h","src/**/*.h") - - -- add_files("proto/*.proto", {rule = "protobuf.cpp", proto_rootdir = "proto"}) - -- add_files("proto/cpp/*.cc") - -- add_headerfiles("proto/cpp/*.h") - before_build(function (target) - os.cd("$(scriptdir)/proto") - os.execv("pb2pbc.bat") - os.exec("pb2cpp.bat") - target:add("files","cpp/*.cc") - target:add("headerfiles","cpp/*.h") - end ) - -- before_package(function(package) - -- print("before_package") - -- end) - -- before_install(function(package) - -- print("before_install") - -- end) - -- before_run(function(package) - -- print("before_run") - -- end) --- add_rules("mode.debug", "mode.release") --- add_requires("protobuf-cpp") - --- target("test") --- set_kind("binary") --- set_languages("c++11") --- add_packages("protobuf-cpp") --- add_rules("protobuf.cpp") --- add_files("src/*.cpp") --- add_files("src/**.proto", {proto_rootdir = "src"}) - diff --git a/src/zasm/.gitignore b/src/zasm/.gitignore new file mode 100644 index 0000000..1521057 --- /dev/null +++ b/src/zasm/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/src/zasm/src/main.cpp b/src/zasm/src/main.cpp new file mode 100644 index 0000000..fbafc96 --- /dev/null +++ b/src/zasm/src/main.cpp @@ -0,0 +1,9 @@ +//#include + +//using namespace std; + +int main(int argc, char** argv) +{ + //cout << "hello world!" << endl; + return 0; +} diff --git a/src/zasm/xmake.lua b/src/zasm/xmake.lua new file mode 100644 index 0000000..a1963fb --- /dev/null +++ b/src/zasm/xmake.lua @@ -0,0 +1,75 @@ +add_rules("mode.debug", "mode.release") + +target("zasm") + set_kind("binary") + add_files("src/*.cpp") + +-- +-- If you want to known more usage about xmake, please see https://xmake.io +-- +-- ## FAQ +-- +-- You can enter the project directory firstly before building project. +-- +-- $ cd projectdir +-- +-- 1. How to build project? +-- +-- $ xmake +-- +-- 2. How to configure project? +-- +-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release] +-- +-- 3. Where is the build output directory? +-- +-- The default output directory is `./build` and you can configure the output directory. +-- +-- $ xmake f -o outputdir +-- $ xmake +-- +-- 4. How to run and debug target after building project? +-- +-- $ xmake run [targetname] +-- $ xmake run -d [targetname] +-- +-- 5. How to install target to the system directory or other output directory? +-- +-- $ xmake install +-- $ xmake install -o installdir +-- +-- 6. Add some frequently-used compilation flags in xmake.lua +-- +-- @code +-- -- add debug and release modes +-- add_rules("mode.debug", "mode.release") +-- +-- -- add macro definition +-- add_defines("NDEBUG", "_GNU_SOURCE=1") +-- +-- -- set warning all as error +-- set_warnings("all", "error") +-- +-- -- set language: c99, c++11 +-- set_languages("c99", "c++11") +-- +-- -- set optimization: none, faster, fastest, smallest +-- set_optimize("fastest") +-- +-- -- add include search directories +-- add_includedirs("/usr/include", "/usr/local/include") +-- +-- -- add link libraries and search directories +-- add_links("tbox") +-- add_linkdirs("/usr/local/lib", "/usr/lib") +-- +-- -- add system link libraries +-- add_syslinks("z", "pthread") +-- +-- -- add compilation and link flags +-- add_cxflags("-stdnolib", "-fno-strict-aliasing") +-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true}) +-- +-- @endcode +-- + diff --git a/src/zcoff/src/COFF_Loader.c b/src/zcoff/src/COFF_Loader.c new file mode 100644 index 0000000..fc9af3b --- /dev/null +++ b/src/zcoff/src/COFF_Loader.c @@ -0,0 +1,407 @@ +#include +#include +#include "coff_definitions.h" +#include "beacon_compatibility.h" +#include "COFF_Loader.h" + + +#pragma region general functions +PBYTE mem_alloc(SIZE_T size, UINT32 flags, UINT32 protection) { + PBYTE ret; + ret = (PBYTE)VirtualAlloc(NULL, size, flags, protection); + return ret; +} +PBYTE coff_read_file(PCHAR filepath) { + HANDLE hFile = NULL; + UINT32 FileSize; + PBYTE buffer = NULL; + + hFile = CreateFileA(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (!hFile) + return NULL; + + FileSize = GetFileSize(hFile, NULL); + if (FileSize == INVALID_FILE_SIZE) + goto cleanup; + + buffer = mem_alloc(FileSize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); + if (!buffer) + goto cleanup; + + if (!ReadFile(hFile, buffer, FileSize, NULL, NULL)) + DEBUG_PRINT("Couldn't read input file! %d\n", GetLastError()); + + if (VirtualProtect(buffer, FileSize, PAGE_READONLY, NULL)) + DEBUG_PRINT("Couldn't change protection to PAGE_READONLY: %d\n", GetLastError); + +cleanup: + CloseHandle(hFile); + return buffer; +} +PUCHAR unpack_arguments(PCHAR arguments, size_t* outlen) { + PUCHAR retval = NULL; + CHAR byteval[2] = { 0 }; + + if (!arguments) + RETURN_NULL_ERROR("No arguments to parse"); + + size_t value_len = strlen((LPCSTR)arguments); + + if (value_len % 2 != 0) + RETURN_NULL_ERROR("The hexlified string isn't valid\n"); + + + retval = mem_alloc(value_len + 1, MEM_COMMIT, PAGE_READWRITE); + if (!retval) + RETURN_NULL_ERROR("couldn't allocate memory for args"); + + /* args are in hex, unpackign */ + for (size_t i = 0; i < value_len; i += 2) { + memcpy(byteval, arguments + i, 2); + CHAR character = strtol(byteval, NULL, 16); + retval[i / 2] = character; + } + + *outlen = value_len / 2; + return retval; +} +LPVOID process_external_symbol(PCHAR symbolstring) { + LPVOID functionaddress = NULL; + CHAR localcopy[1024] = { 0 }; + PCHAR locallib = NULL; + PCHAR localfunc = NULL; + HMODULE llHandle = NULL; + PCHAR therest = NULL; + + + CHAR prefix[] = "__imp_"; + CHAR prefix_beacon[] = "__imp_Beacon"; + CHAR prefix_towidechar[] = "__imp_toWideChar"; + size_t prefix_len = strlen(prefix); + + /* the symbol name doesn't conform to our naming convention */ + if (strncmp(symbolstring, prefix, strlen(prefix))) + RETURN_NULL_ERROR("not conforming to our naming convention\n"); + + + /* check if it's an internal beacon function */ + if (strncmp(symbolstring, prefix_beacon, strlen(prefix_beacon)) == 0 + || strncmp(symbolstring, prefix_towidechar, strlen(prefix_towidechar)) == 0) { + + localfunc = symbolstring + prefix_len; + + for (int i = 0; i < 25; i++) { + if (InternalFunctions[i][0] != NULL) { + if (strcmp(localfunc, (PCHAR)(InternalFunctions[i][0])) == 0) { + functionaddress = (PCHAR)InternalFunctions[i][1]; + return functionaddress; + } + } + } + } + + /* if we are here, it is an external function */ + strcpy_s(localcopy, _countof(localcopy), symbolstring); + locallib = strtok_s(localcopy + prefix_len, "$@", &therest); + localfunc = strtok_s(therest, "$@", &therest); + if (!localfunc || !locallib) + RETURN_NULL_ERROR("couldn't extract external function name, %s\n", symbolstring) + + llHandle = LoadLibraryA(locallib); + if (llHandle) { + functionaddress = GetProcAddress(llHandle, localfunc); + if (!functionaddress) + RETURN_NULL_ERROR("No func %s in %s\n", localfunc, locallib); + // FreeLibrary(llHandle); // we can't free the library until execution is done. TODO: keep a list of loaded dll per bof to unload after execution + } + else { + RETURN_NULL_ERROR("couldn't load library %s\n", locallib) + } + return functionaddress; +} +#pragma endregion + +#pragma region relocation functions +UINT32 read32le(const PUINT8 p) +{ + /* The one true way, see + * https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html */ + return ((UINT32)p[0] << 0) | + ((UINT32)p[1] << 8) | + ((UINT32)p[2] << 16) | + ((UINT32)p[3] << 24); +} +VOID write32le(PUINT8 dst, UINT32 x) +{ + dst[0] = (UINT8)(x >> 0); + dst[1] = (UINT8)(x >> 8); + dst[2] = (UINT8)(x >> 16); + dst[3] = (UINT8)(x >> 24); +} +VOID add32(PUINT8 P, UINT32 V) { write32le(P, read32le(P) + V); } +VOID coff_apply_relocations(PUINT32 P, PBYTE S, UINT16 Type, UINT32 SymOffset) { + + switch (Type) + { + case IMAGE_REL_AMD64_REL32: add32(P, S + SymOffset - (PBYTE)P - 4); break; + case IMAGE_REL_AMD64_ADDR32NB: add32(P, S - (PBYTE)P - 4); break; + case IMAGE_REL_AMD64_ADDR64:*P = (*P + S); break; +// working alternatives +// case IMAGE_REL_AMD64_REL32: *P += (S + SymOffset - P - 4); break; +// case IMAGE_REL_AMD64_ADDR32NB: *P = (S - P - 4); break; +// case IMAGE_REL_AMD64_ADDR64: *P = (*P + S); break; + default: + DEBUG_PRINT("NO CODE TO RELOCATE TYPE: %d\n", Type); + break; + } + +} +#pragma endregion + +#pragma region coff helper functions +SymbolTableEntry* coff_get_symbol_table(PBYTE pImageBase) { + if (!pImageBase) + return NULL; + + return (SymbolTableEntry*)(pImageBase + ((FileHeader*)pImageBase)->PointerToSymbolTable); +} +UINT32 coff_get_ext_function_space(PBYTE pImageBase) { + UINT32 ret = 0; + SymbolTableEntry* pSymbolTable; + RelocationTableEntry* reloc; + SectionHeader* pTextSectionHeader; + if (!pImageBase) + return 0; //TODO: This is not optimal because it may lead to crashes if external functions exist but NULL is passed + + pTextSectionHeader = coff_get_text_section_header(pImageBase); + pSymbolTable = coff_get_symbol_table(pImageBase); + reloc = (RelocationTableEntry*)(pImageBase + pTextSectionHeader->PointerToRelocations); + if (!pTextSectionHeader || !pSymbolTable) + RETURN_ERROR("couldn't get symbol table or text section"); + + for (int i = 0; i < pTextSectionHeader->NumberOfRelocations; i++) + { + SymbolTableEntry* sym = pSymbolTable + reloc->SymbolTableIndex; + /* The External storage class may include functions in the .text section as well (internal functions). + To ensure that only external functions are included, a check for the section number is added. + A section number of 0 == UNDEF section, which is the case for external functions. + */ + if (sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && sym->SectionNumber == 0) + { + ret++; + } + reloc++; + } + return ret * sizeof(PBYTE); +} +BOOL coff_execute_entry(coff_object coff, PCHAR func, PUCHAR args, UINT32 argSize) { + VOID(*foo)(PCHAR in, UINT32 datalen) = NULL; + + if (!func || !coff.pImageBase) + RETURN_ERROR("no entry provided"); + + for (UINT32 counter = 0; counter < ((FileHeader*)coff.pImageBase)->NumberOfSymbols; counter++) + { + if (strcmp(coff.symbol_table[counter].first.Name, func) == 0) { + // foo = (PCHAR)coff.pTextSectionRawData; to my surprise, this won't work! It appears that go isn't always at the beginning of the .text section! + foo = (PCHAR)(coff.pTextSectionRawData + coff.symbol_table[counter].Value); + DEBUG_PRINT("Trying to run: %p\n", foo); + } + } + + if (!foo) + RETURN_ERROR("couldn't find entry point"); + + foo(args, argSize); + return TRUE; +} +SectionHeader* coff_get_text_section_header(PBYTE pImageBase) { + + FileHeader* pFileHeader; + + if (!pImageBase) + return NULL; + + pFileHeader = (FileHeader*)pImageBase; + + for (int i = 0; i < pFileHeader->NumberOfSections; i++) + { + SectionHeader* pSectionHeader = (SectionHeader*)(pImageBase + sizeof(FileHeader) + (sizeof(SectionHeader) * i)); + if (strstr(pSectionHeader->Name, ".text")) + return pSectionHeader; + } + + return NULL; +} +BOOL coff_extract_text_section(PBYTE pImageBase, coff_object* coff) { + + UINT32 sizeOfData; + SectionHeader* pTextSectionHeader; + + if (!coff || !pImageBase) + RETURN_ERROR("invalid args"); + + coff->pImageBase = pImageBase; + coff->symbol_table = coff_get_symbol_table(pImageBase); + + pTextSectionHeader = coff_get_text_section_header(pImageBase); + if (!pTextSectionHeader) + RETURN_ERROR("pTextHeader is null"); + + coff->pTextSectionHeader = pTextSectionHeader; + sizeOfData = pTextSectionHeader->SizeOfRawData + coff_get_ext_function_space(pImageBase); + coff->pTextSectionRawData = mem_alloc(sizeOfData, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE); + if (!coff->pTextSectionRawData) + RETURN_ERROR("couldn't allocate new .text section"); + + memcpy(coff->pTextSectionRawData, + pImageBase + pTextSectionHeader->PointerToRawData, + pTextSectionHeader->SizeOfRawData); + + return TRUE; +} +PBYTE coff_get_section_raw_data_by_index(PBYTE pImageBase, UINT32 index) { + SectionHeader* pSectionHeader; + + if (!pImageBase) + return NULL; + + pSectionHeader = (SectionHeader*)(pImageBase + sizeof(FileHeader) + (sizeof(SectionHeader) * index)); + + return pImageBase + pSectionHeader->PointerToRawData; +} +BOOL coff_relocate_text_section(coff_object coff) { + + UINT32 functionMappingCount = 0; + PBYTE current_section_ptr; + RelocationTableEntry* Reloc; + + + current_section_ptr = coff.pTextSectionRawData; + if (!current_section_ptr) + RETURN_ERROR(".text is null"); + + Reloc = (RelocationTableEntry*)(coff.pImageBase + coff.pTextSectionHeader->PointerToRelocations); + + for (int ireloc = 0; ireloc < coff.pTextSectionHeader->NumberOfRelocations; ireloc++) + { + UINT16 TargetSectionIndex; + SymbolTableEntry* sym; + BOOL isExternal, isInternal; + PUINT32 P; /* Location to patch */ + + TargetSectionIndex = coff.symbol_table[Reloc->SymbolTableIndex].SectionNumber - 1; + sym = coff.symbol_table + Reloc->SymbolTableIndex; + isExternal = (sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && sym->SectionNumber == 0); + isInternal = (sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && sym->SectionNumber != 0); + + + P = (PUINT32)( + current_section_ptr + + Reloc->VirtualAddress + - coff.pTextSectionHeader->VirtualAddress); + + if (isExternal) + { + PUINT64 pFunction; + UINT32 StringTableOffset = sym->first.value[1]; + PCHAR function_full_name = ((PCHAR)(coff.symbol_table + ((FileHeader*)coff.pImageBase)->NumberOfSymbols) + StringTableOffset); + PUINT64 func_addr2 = (PUINT64)(current_section_ptr + coff.pTextSectionHeader->SizeOfRawData); + + pFunction = process_external_symbol(function_full_name); + + if (pFunction) + { + /* copy the address of the ext. function into the region right after the .text section */ + *(func_addr2 + (functionMappingCount)) = (UINT64)pFunction; + + /* calculate the difference between P and the copied ext. func addr */ + UINT32 v = (UINT32)((UINT32)(func_addr2 + (functionMappingCount)) - (UINT32)(P)-4); + + /* copy the difference to P */ + *(PINT32)P = v; + functionMappingCount += 1; + } + else { + RETURN_ERROR("couldn't resolve function"); + } + } + else { + /* not an external function, could be either internal or data + if it's an internal function, then the target section should be the text + section. Otherwise, the target section should be whatever section the data + is in. + + The reason that .text section is having a special treatment here is because + we re-allocated it to another region in memory to make it executable. If we + use coff_get_section_by_index for the text section, we will get a pointer to + the original text_section, which is not in an executable memory region. + + This can be simplified by allocating executable memory for the entire coff. I wasn't sure about the + detection complications in an executable memory for the entire coff so decided to stick to only the + .text section. Maybe in future versions I'll simplifythis by having the entire coff in an + executable region. + + */ + PBYTE S = coff_get_section_raw_data_by_index(coff.pImageBase, TargetSectionIndex); + if (!S) + RETURN_ERROR("target section is null"); + + /* VS compiler won't patch relative addresses of internal functions for us so we have to do it ourselves */ + if (isInternal) + S = coff.pTextSectionRawData; + + coff_apply_relocations(P, S, Reloc->Type, sym->Value); + } + Reloc++; + } + return TRUE; +} +#pragma endregion + +void main(int argc, char* argv[]) { + + PBYTE coff_data = NULL; + coff_object coff; + PCHAR arguments = NULL; + size_t arg_size = 0; + + if (argc < 2) { + printf("not enough args...\nUsage: %s [path_to_obj_file] ", argv[0]); + return; + } + + coff_data = coff_read_file(argv[1]); + if (!coff_data) + return; + + if(argv[2]) + arguments = unpack_arguments(argv[2], &arg_size); + + if (!coff_extract_text_section(coff_data, &coff)) + goto cleanup; + + + if (!coff_relocate_text_section(coff)) + goto cleanup; + + + if (!coff_execute_entry(coff, "go", arguments, (UINT32)arg_size)) + goto cleanup; + + PCHAR outdata = BeaconGetOutputData(NULL); + if (outdata != NULL) { + printf("\nOutdata Below:\n\n%s\n", outdata); + } + +cleanup: + if(coff_data) + VirtualFree(coff_data, 0, MEM_RELEASE); + if (coff.pTextSectionRawData) + VirtualFree(coff.pTextSectionRawData, 0, MEM_RELEASE); + if (arguments) + VirtualFree(arguments, 0, MEM_RELEASE); +} + + + diff --git a/src/zcoff/src/COFF_Loader.h b/src/zcoff/src/COFF_Loader.h new file mode 100644 index 0000000..0364a8f --- /dev/null +++ b/src/zcoff/src/COFF_Loader.h @@ -0,0 +1,114 @@ +#pragma once +#include "coff_definitions.h" + +typedef struct { + PBYTE pImageBase; + SectionHeader* pTextSectionHeader; + PBYTE pTextSectionRawData; + SymbolTableEntry* symbol_table; +} coff_object; + +#pragma region error_handling +#define RETURN_ERROR(x, ...) { printf(x, ##__VA_ARGS__); return FALSE; } +#define RETURN_NULL_ERROR(x, ...) { printf(x, ##__VA_ARGS__); return NULL;} +#define DEBUG_PRINT(x, ...) printf(x, ##__VA_ARGS__) +#pragma endregion + +/// +/// Reads a coff from a specified path, no parsing is done in this function +/// +/// path to coff object location +/// a read/write pointer to in-memory coff object +PBYTE coff_read_file(PCHAR filepath); + +/// +/// Unpack packed arguments for CS compatibility +/// +/// hex string representing args +/// on success, returns the total size of the args +/// unpacked arguments +PUCHAR unpack_arguments(PCHAR arguments, size_t* outlen); + +/// +/// Finds the address of an external symbol that was created using lib$func naming convention +/// +/// a string containing a lib$func to be resolved +/// address to resolved external function +LPVOID process_external_symbol(PCHAR symbolstring); + +/// +/// generic function to apply coff relocations, some reloc types aren't implemented yet +/// +/// The location to be patched +/// The target section (section containing the actual data) +/// The type of the relocation +/// The symbol offset in the symbol table +VOID coff_apply_relocations(PUINT32 P, PBYTE S, UINT16 Type, UINT32 SymOffset); + +/// +/// Calculates the size needed to store pointers for external functions right after the text section +/// +/// pointer to coff image base +/// number of external symbols * sizeof(pointer) +UINT32 coff_get_ext_function_space(PBYTE pImageBase); + +/// +/// +/// +/// pointer to coff image base +/// pointer to the symbol table +SymbolTableEntry* coff_get_symbol_table(PBYTE pImageBase); + +/// +/// allocates memory using VirtualAlloc, can be easily modified to allocate using whatever method +/// +/// nr of bytes to be allocated +/// dwFlags from VirtualAlloc +/// dwProtection from VirtualAlloc +/// pointer to allocated memory +PBYTE mem_alloc(SIZE_T size, UINT32 flags, UINT32 protection); + +/// +/// Returns a pointer to the text section header. The text section header is a special case because we have +/// to use strstr() instead of strcmp() since MSVC will generate ".text$mn" while gcc will generate ".text". +/// We cannot use strstr() with every section header because MSVC will generate .rdata while gcc will generate +/// ".rdata$zzz", so I decided to have a separate function for .text section header +/// +/// pointer to coff image base +/// pointer to .text section header or null on failure +SectionHeader* coff_get_text_section_header(PBYTE pImageBase); + +/// +/// Extracts the .text section into a PAGE_EXECUTE_READWRITE memory region +/// +/// pointer to coff image base +/// a pointer to a coff_object struct to make my life easier +/// true if creation of new memory region succeeded, the new .text section will be stored in the coff_object +BOOL coff_extract_text_section(PBYTE pImageBase, coff_object* coff); + +/// +/// executes the coff entry function +/// +/// pointer to coff_object struct +/// pointer to the name of entry function, usually "go" +/// unpacked arguments +/// the size of the arguments +/// true if execution took place +BOOL coff_execute_entry(coff_object coff, PCHAR entry_name, PUCHAR args, UINT32 argSize); + +/// +/// Returns the raw data of the target section, which is identified by its index. Useful in relocations +/// where we know the index of the target section and have to access its data. +/// +/// pointer to coff image base +/// the index of the target section +/// a pointer to the beginning of the target section +PBYTE coff_get_section_raw_data_by_index(PBYTE pImageBase, UINT32 index); + +/// +/// Relocates the .text section of the coff file. The reason I chose to only relocate the .text sections +/// is because coff object execution only needs .text relocation. +/// +/// coff_object struct that is pre-filled by calling coff_extract_text_section first +/// true if relocations are performed without errors +BOOL coff_relocate_text_section(coff_object coff); \ No newline at end of file diff --git a/src/zcoff/src/README.md b/src/zcoff/src/README.md new file mode 100644 index 0000000..5dcd379 --- /dev/null +++ b/src/zcoff/src/README.md @@ -0,0 +1,32 @@ +# COFFLoader2 + +This repo contains the source code of a Common Object File Format (COFF) loader, which is a rewrite of the research and implementation done by Kevin Haubris [@Kev169](https://twitter.com/kev169) on the [TrustedSec](https://www.trustedsec.com) GitHub repo [here](https://github.com/trustedsec/COFFLoader). Kevin also wrote an article about [building your own COFF loader](https://www.trustedsec.com/blog/coffloader-building-your-own-in-memory-loader-or-how-to-run-bofs/) + +Kevin did an excellent job in figuring out the relocations and implementing the beacon compatibility layer. This repo takes it a bit further in making the code prettier (beauty is in the eyes of the beholder anyway) and more readable. This repo includes more comments, extracted COFF-related code into re-usable functions, usage of MSVC-compliant functions, and fix issues with MSVC-compiled BOFs. Also, while the code is initially inspired by Kevin's work, the approach to the implementation of the relocations and memory allocation is different. + +### Why? + +Rewriting code is an excellent way to improve one's understanding of a topic. This was the main drive for rewriting the code. Another reason is that the original code is *probably* not meant for the VS toolchain, which is apparent in the fact that MSVC won't compile the code because of its insecure-function warnings and that the loader won't load MSVC-compiled BOFs. Since I like developing and compiling my BOFs with VS, this was another good reason to rewrite. Further, the original code seemed too complicated to my simple brain. For example, when I was trying to understand the original code, I found myself reading an `if statement` which is inside an `else if` that is inside another `else` which is inside a `for` loop that is inside another `for` loop. My brain couldn't keep up, the folks at TrustedSec are too smart for me haha. The code also lacked variables which made it quite challenging to read, so a rewrite seemed definitely worth the time and effort. Looking retrospectively, I am pretty happy about the decision! + +### What? + +The rewrite is focussed on the COFF-loading process only. I did not modify the beacon compatibility layer. A non-comprehensive list of changes + +- Re-implemented the relocations. The code now performs relocations on the .text section only, which is sufficient to get the COFF executed. However, applying the relocations to any other section should be straightforward with the new structure +- Improved readability by removing some nesting, using variables, and extracting some re-usable code into functions +- Used WIN32 API calls to open and read the file instead of the standard library functions +- Avoid double allocation for every section. The exception is .text section which is allocated again on PAGE_EXECUTE_READWRITE memory region. The other sections are located in PAGE_READONLY memory region. +- Removed fixed-size allocation for function mapping and check of whether the mapping is within 4GB limit by ensuring that the mapping will be right after the .text section. +- Added more error checking here and there + +### Todo + +While I didn't have any issues with testing, I'll maintain the original disclaimer. This code should be used for testing purposes, it needs further testing before using in production. + +What I'd like to do from here is using the loader over the network and take a deeper look into the beacon compatibility layer to see how this can be transformed into a COFF-based C2 and perhaps add x86 support. Much more can be added/modified but at one point I realized that the cycle of refactoring can continue forever and wanted to share a first version. Hopefully a blog post and more comments will follow. + +### Credits + +1. Huge thanks to Kevin [@Kev169](https://twitter.com/kev169) and the TrustedSec team for sharing their code. Going through the code and rewriting it made me realize the great effort and time invested in the original implementation. Great job Kevin and TrustedSec! +2. Patryk Czeczko ([@0xpat](https://twitter.com/0xPat)) wrote a nice blog article about COFF loaders [on his blog](https://0xpat.github.io/Malware_development_part_8/), was quite useful +3. While not directly related to the re-implementation, I liked the [BOF2Shellcode](https://medium.com/falconforce/bof2shellcode-a-tutorial-converting-a-stand-alone-bof-loader-into-shellcode-6369aa518548) article by Gijs Hollestelle ([@gijs_h](https://twitter.com/gijs_h)) and found it to be an exciting read. diff --git a/src/zcoff/src/beacon_compatibility.c b/src/zcoff/src/beacon_compatibility.c new file mode 100644 index 0000000..da17a45 --- /dev/null +++ b/src/zcoff/src/beacon_compatibility.c @@ -0,0 +1,350 @@ +/* + * Cobalt Strike 4.X BOF compatibility layer + * ----------------------------------------- + * The whole point of these files are to allow beacon object files built for CS + * to run fine inside of other tools without recompiling. + * + * Built off of the beacon.h file provided to build for CS. + */ + + +#include +#include +#include +#include +#ifdef _WIN32 +#include + +#include "beacon_compatibility.h" + +#define DEFAULTPROCESSNAME "rundll32.exe" +#ifdef _WIN64 +#define X86PATH "SysWOW64" +#define X64PATH "System32" +#else +#define X86PATH "System32" +#define X64PATH "sysnative" +#endif + + + /* Data Parsing */ +unsigned char* InternalFunctions[25][2] = { + {(unsigned char*)"BeaconDataParse", (unsigned char*)BeaconDataParse}, + {(unsigned char*)"BeaconDataInt", (unsigned char*)BeaconDataInt}, + {(unsigned char*)"BeaconDataShort", (unsigned char*)BeaconDataShort}, + {(unsigned char*)"BeaconDataLength", (unsigned char*)BeaconDataLength}, + {(unsigned char*)"BeaconDataExtract", (unsigned char*)BeaconDataExtract}, + {(unsigned char*)"BeaconFormatAlloc", (unsigned char*)BeaconFormatAlloc}, + {(unsigned char*)"BeaconFormatReset", (unsigned char*)BeaconFormatReset}, + {(unsigned char*)"BeaconFormatFree", (unsigned char*)BeaconFormatFree}, + {(unsigned char*)"BeaconFormatAppend", (unsigned char*)BeaconFormatAppend}, + {(unsigned char*)"BeaconFormatPrintf", (unsigned char*)BeaconFormatPrintf}, + {(unsigned char*)"BeaconFormatToString", (unsigned char*)BeaconFormatToString}, + {(unsigned char*)"BeaconFormatInt", (unsigned char*)BeaconFormatInt}, + {(unsigned char*)"BeaconPrintf", (unsigned char*)BeaconPrintf}, + {(unsigned char*)"BeaconOutput", (unsigned char*)BeaconOutput}, + {(unsigned char*)"BeaconUseToken", (unsigned char*)BeaconUseToken}, + {(unsigned char*)"BeaconRevertToken", (unsigned char*)BeaconRevertToken}, + {(unsigned char*)"BeaconIsAdmin", (unsigned char*)BeaconIsAdmin}, + {(unsigned char*)"BeaconGetSpawnTo", (unsigned char*)BeaconGetSpawnTo}, + {(unsigned char*)"BeaconSpawnTemporaryProcess", (unsigned char*)BeaconSpawnTemporaryProcess}, + {(unsigned char*)"BeaconInjectProcess", (unsigned char*)BeaconInjectProcess}, + {(unsigned char*)"BeaconInjectTemporaryProcess", (unsigned char*)BeaconInjectTemporaryProcess}, + {(unsigned char*)"BeaconCleanupProcess", (unsigned char*)BeaconCleanupProcess}, + {(unsigned char*)"toWideChar", (unsigned char*)toWideChar} +}; + +uint32_t swap_endianess(uint32_t indata) { + uint32_t testint = 0xaabbccdd; + uint32_t outint = indata; + if (((unsigned char*)&testint)[0] == 0xdd) { + ((unsigned char*)&outint)[0] = ((unsigned char*)&indata)[3]; + ((unsigned char*)&outint)[1] = ((unsigned char*)&indata)[2]; + ((unsigned char*)&outint)[2] = ((unsigned char*)&indata)[1]; + ((unsigned char*)&outint)[3] = ((unsigned char*)&indata)[0]; + } + return outint; +} + +char* beacon_compatibility_output = NULL; +int beacon_compatibility_size = 0; +int beacon_compatibility_offset = 0; + +void BeaconDataParse(datap* parser, char* buffer, int size) { + if (parser == NULL) { + return; + } + parser->original = buffer; + parser->buffer = buffer; + parser->length = size - 4; + parser->size = size - 4; + parser->buffer += 4; + return; +} + +int BeaconDataInt(datap* parser) { + int32_t fourbyteint = 0; + if (parser->length < 4) { + return 0; + } + memcpy(&fourbyteint, parser->buffer, 4); + parser->buffer += 4; + parser->length -= 4; + return (int)fourbyteint; +} + +short BeaconDataShort(datap* parser) { + int16_t retvalue = 0; + if (parser->length < 2) { + return 0; + } + memcpy(&retvalue, parser->buffer, 2); + parser->buffer += 2; + parser->length -= 2; + return (short)retvalue; +} + +int BeaconDataLength(datap* parser) { + return parser->length; +} + +char* BeaconDataExtract(datap* parser, int* size) { + uint32_t length = 0; + char* outdata = NULL; + /*Length prefixed binary blob, going to assume uint32_t for this.*/ + if (parser->length < 4) { + return NULL; + } + memcpy(&length, parser->buffer, 4); + parser->buffer += 4; + + outdata = parser->buffer; + if (outdata == NULL) { + return NULL; + } + parser->length -= 4; + parser->length -= length; + parser->buffer += length; + if (size != NULL && outdata != NULL) { + *size = length; + } + return outdata; +} + +/* format API */ + +void BeaconFormatAlloc(formatp* format, int maxsz) { + if (format == NULL) { + return; + } + format->original = calloc(maxsz, 1); + format->buffer = format->original; + format->length = 0; + format->size = maxsz; + return; +} + +void BeaconFormatReset(formatp* format) { + memset(format->original, 0, format->size); + format->buffer = format->original; + format->length = format->size; + return; +} + +void BeaconFormatFree(formatp* format) { + if (format == NULL) { + return; + } + if (format->original) { + free(format->original); + format->original = NULL; + } + format->buffer = NULL; + format->length = 0; + format->size = 0; + return; +} + +void BeaconFormatAppend(formatp* format, char* text, int len) { + memcpy(format->buffer, text, len); + format->buffer += len; + format->length += len; + return; +} + +void BeaconFormatPrintf(formatp* format, char* fmt, ...) { + /*Take format string, and sprintf it into here*/ + va_list args; + int length = 0; + + va_start(args, fmt); + length = vsnprintf(NULL, 0, fmt, args); + va_end(args); + if (format->length + length > format->size) { + return; + } + + va_start(args, fmt); + (void)vsnprintf(format->buffer, length, fmt, args); + va_end(args); + format->length += length; + format->buffer += length; + return; +} + + +char* BeaconFormatToString(formatp* format, int* size) { + *size = format->length; + return format->original; +} + +void BeaconFormatInt(formatp* format, int value) { + uint32_t indata = value; + uint32_t outdata = 0; + if (format->length + 4 > format->size) { + return; + } + outdata = swap_endianess(indata); + memcpy(format->buffer, &outdata, 4); + format->length += 4; + format->buffer += 4; + return; +} + +/* Main output functions */ + +void BeaconPrintf(int type, char* fmt, ...) { + /* Change to maintain internal buffer, and return after done running. */ + int length = 0; + char* tempptr = NULL; + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + va_start(args, fmt); + length = vsnprintf(NULL, 0, fmt, args); + va_end(args); + tempptr = realloc(beacon_compatibility_output, beacon_compatibility_size + length + 1); + if (tempptr == NULL) { + return; + } + beacon_compatibility_output = tempptr; + memset(beacon_compatibility_output + beacon_compatibility_offset, 0, length + 1); + va_start(args, fmt); + length = vsnprintf(beacon_compatibility_output + beacon_compatibility_offset, length, fmt, args); + beacon_compatibility_size += length; + beacon_compatibility_offset += length; + va_end(args); + return; +} + +void BeaconOutput(int type, char* data, int len) { + char* tempptr = NULL; + tempptr = realloc(beacon_compatibility_output, beacon_compatibility_size + len + 1); + beacon_compatibility_output = tempptr; + if (tempptr == NULL) { + return; + } + memset(beacon_compatibility_output + beacon_compatibility_offset, 0, len + 1); + memcpy(beacon_compatibility_output + beacon_compatibility_offset, data, len); + beacon_compatibility_size += len; + beacon_compatibility_offset += len; + return; +} + +/* Token Functions */ + +BOOL BeaconUseToken(HANDLE token) { + /* Probably needs to handle DuplicateTokenEx too */ + SetThreadToken(NULL, token); + return TRUE; +} + +void BeaconRevertToken(void) { + if (!RevertToSelf()) { +#ifdef DEBUG + printf("RevertToSelf Failed!\n"); +#endif + } + return; +} + +BOOL BeaconIsAdmin(void) { + /* Leaving this to be implemented by people needing it */ +#ifdef DEBUG + printf("BeaconIsAdmin Called\n"); +#endif + return FALSE; +} + +/* Injection/spawning related stuffs + * + * These functions are basic place holders, and if implemented into something + * real should be just calling internal functions for your tools. */ +void BeaconGetSpawnTo(BOOL x86, char* buffer, int length) { + char* tempBufferPath = NULL; + if (buffer == NULL) { + return; + } + if (x86) { + tempBufferPath = "C:\\Windows\\"X86PATH"\\"DEFAULTPROCESSNAME; + if (strlen(tempBufferPath) > length) { + return; + } + memcpy(buffer, tempBufferPath, strlen(tempBufferPath)); + } + else { + tempBufferPath = "C:\\Windows\\"X64PATH"\\"DEFAULTPROCESSNAME; + if (strlen(tempBufferPath) > length) { + return; + } + memcpy(buffer, tempBufferPath, strlen(tempBufferPath)); + + } + return; +} + +BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO* sInfo, PROCESS_INFORMATION* pInfo) { + BOOL bSuccess = FALSE; + if (x86) { + bSuccess = CreateProcessA(NULL, (char*)"C:\\Windows\\"X86PATH"\\"DEFAULTPROCESSNAME, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, sInfo, pInfo); + } + else { + bSuccess = CreateProcessA(NULL, (char*)"C:\\Windows\\"X64PATH"\\"DEFAULTPROCESSNAME, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, sInfo, pInfo); + } + return bSuccess; +} + +void BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len) { + /* Leaving this to be implemented by people needing/wanting it */ + return; +} + +void BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len) { + /* Leaving this to be implemented by people needing/wanting it */ + return; +} + +void BeaconCleanupProcess(PROCESS_INFORMATION* pInfo) { + (void)CloseHandle(pInfo->hThread); + (void)CloseHandle(pInfo->hProcess); + return; +} + +BOOL toWideChar(char* src, wchar_t* dst, int max) { + /* Leaving this to be implemented by people needing/wanting it */ + return FALSE; +} + +char* BeaconGetOutputData(int* outsize) { + char* outdata = beacon_compatibility_output; + if (outsize) + *outsize = beacon_compatibility_size; + beacon_compatibility_output = NULL; + beacon_compatibility_size = 0; + beacon_compatibility_offset = 0; + return outdata; +} + +#endif diff --git a/src/zcoff/src/beacon_compatibility.h b/src/zcoff/src/beacon_compatibility.h new file mode 100644 index 0000000..f1e716e --- /dev/null +++ b/src/zcoff/src/beacon_compatibility.h @@ -0,0 +1,69 @@ +/* + * Cobalt Strike 4.X BOF compatibility layer + * ----------------------------------------- + * The whole point of these files are to allow beacon object files built for CS + * to run fine inside of other tools without recompiling. + * + * Built off of the beacon.h file provided to build for CS. + */ + +#include + +#ifndef BEACON_COMPATIBILITY_H_ + /* Structures as is in beacon.h */ +extern unsigned char* InternalFunctions[25][2]; +typedef struct { + char* original; /* the original buffer [so we can free it] */ + char* buffer; /* current pointer into our buffer */ + int length; /* remaining length of data */ + int size; /* total size of this buffer */ +} datap; + +typedef struct { + char* original; /* the original buffer [so we can free it] */ + char* buffer; /* current pointer into our buffer */ + int length; /* remaining length of data */ + int size; /* total size of this buffer */ +} formatp; + +void BeaconDataParse(datap* parser, char* buffer, int size); +int BeaconDataInt(datap* parser); +short BeaconDataShort(datap* parser); +int BeaconDataLength(datap* parser); +char* BeaconDataExtract(datap* parser, int* size); + +void BeaconFormatAlloc(formatp* format, int maxsz); +void BeaconFormatReset(formatp* format); +void BeaconFormatFree(formatp* format); +void BeaconFormatAppend(formatp* format, char* text, int len); +void BeaconFormatPrintf(formatp* format, char* fmt, ...); +char* BeaconFormatToString(formatp* format, int* size); +void BeaconFormatInt(formatp* format, int value); + +#define CALLBACK_OUTPUT 0x0 +#define CALLBACK_OUTPUT_OEM 0x1e +#define CALLBACK_ERROR 0x0d +#define CALLBACK_OUTPUT_UTF8 0x20 + + +void BeaconPrintf(int type, char* fmt, ...); +void BeaconOutput(int type, char* data, int len); + +/* Token Functions */ +BOOL BeaconUseToken(HANDLE token); +void BeaconRevertToken(); +BOOL BeaconIsAdmin(); + +/* Spawn+Inject Functions */ +void BeaconGetSpawnTo(BOOL x86, char* buffer, int length); +BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO* sInfo, PROCESS_INFORMATION* pInfo); +void BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len); +void BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len); +void BeaconCleanupProcess(PROCESS_INFORMATION* pInfo); + +/* Utility Functions */ +BOOL toWideChar(char* src, wchar_t* dst, int max); +uint32_t swap_endianess(uint32_t indata); + +char* BeaconGetOutputData(int* outsize); +#endif diff --git a/src/zcoff/src/coff_definitions.h b/src/zcoff/src/coff_definitions.h new file mode 100644 index 0000000..610c4e2 --- /dev/null +++ b/src/zcoff/src/coff_definitions.h @@ -0,0 +1,118 @@ +#pragma once +#include + +// +//Microsoft COFF Header +//Section Headers +//Raw Data : +//code +//data +//debug info +//relocations +#pragma pack (push, 1) +typedef struct { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} FileHeader; + + +/// +/// Just a test! +/// +typedef struct { + char Name[8]; //8 bytes long null-terminated string + UINT32 VirtualSize; //total size of section when loaded into memory, 0 for COFF, might be different because of padding + UINT32 VirtualAddress; //address of the first byte of the section before relocations are applied, should be set to 0 + UINT32 SizeOfRawData; //The size of the section for COFF files + UINT32 PointerToRawData; //Pointer to the beginning of the section for COFF + UINT32 PointerToRelocations; //File pointer to the beginning of relocation entries + UINT32 PointerToLinenumbers; //The file pointer to the beginning of line-number entries for the section. T + UINT16 NumberOfRelocations; //The number of relocation entries for the section. This is set to zero for executable images. + UINT16 NumberOfLinenumbers; //The number of line-number entries for the section. This value should be zero for an image because COFF debugging information is deprecated. + UINT32 Characteristics; //The flags that describe the characteristics of the section +} SectionHeader; + + +typedef struct { + union { + char Name[8]; //8 bytes, name of the symbol, represented as a union of 3 structs + UINT32 value[2]; //TODO: what does this represent?! + } first; + UINT32 Value; //meaning depends on the section number and storage class + UINT16 SectionNumber; //signed int, some values have predefined meaning + UINT16 Type; // + UINT8 StorageClass; // + UINT8 NumberOfAuxSymbols; +} SymbolTableEntry; + + +typedef struct { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} RelocationTableEntry; + +#pragma pack(pop) + + +#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 +#define IMAGE_REL_AMD64_ADDR64 0x0001 +#define IMAGE_REL_AMD64_ADDR32 0x0002 +#define IMAGE_REL_AMD64_ADDR32NB 0x0003 +/* Most common from the looks of it, just 32-bit relative address from the byte following the relocation */ +#define IMAGE_REL_AMD64_REL32 0x0004 +/* Second most common, 32-bit address without an image base. Not sure what that means... */ +#define IMAGE_REL_AMD64_REL32_1 0x0005 +#define IMAGE_REL_AMD64_REL32_2 0x0006 +#define IMAGE_REL_AMD64_REL32_3 0x0007 +#define IMAGE_REL_AMD64_REL32_4 0x0008 +#define IMAGE_REL_AMD64_REL32_5 0x0009 +#define IMAGE_REL_AMD64_SECTION 0x000A +#define IMAGE_REL_AMD64_SECREL 0x000B +#define IMAGE_REL_AMD64_SECREL7 0x000C +#define IMAGE_REL_AMD64_TOKEN 0x000D +#define IMAGE_REL_AMD64_SREL32 0x000E +#define IMAGE_REL_AMD64_PAIR 0x000F +#define IMAGE_REL_AMD64_SSPAN32 0x0010 + + +// +// Storage classes. +// +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0x0000 +#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 +#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 +#define IMAGE_SYM_CLASS_STATIC 0x0003 +#define IMAGE_SYM_CLASS_REGISTER 0x0004 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 +#define IMAGE_SYM_CLASS_LABEL 0x0006 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 +#define IMAGE_SYM_CLASS_ARGUMENT 0x0009 +#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B +#define IMAGE_SYM_CLASS_UNION_TAG 0x000C +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E +#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 +#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 +#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 +#define IMAGE_SYM_CLASS_BLOCK 0x0064 +#define IMAGE_SYM_CLASS_FUNCTION 0x0065 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 +#define IMAGE_SYM_CLASS_FILE 0x0067 +#define IMAGE_SYM_CLASS_SECTION 0x0068 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 +#define IMAGE_SYM_CLASS_CLR_TOKEN 0x006B + + +//the $ is used to group sections in object files. It doesn't exist in image files +//the linker will remove $ and its suffix. sect1$c comes before sect1$c and after sect1$a \ No newline at end of file diff --git a/src/zcoff/xmake.lua b/src/zcoff/xmake.lua new file mode 100644 index 0000000..275b017 --- /dev/null +++ b/src/zcoff/xmake.lua @@ -0,0 +1,7 @@ +target("zcoff") + set_rundir(".") + set_kind("binary") + add_files("src/*.c") + add_syslinks("Advapi32") + add_headerfiles("src/*.h") + set_runargs("file/main.cpp.obj") \ No newline at end of file diff --git a/src/zcore/.gitignore b/src/zcore/.gitignore new file mode 100644 index 0000000..1521057 --- /dev/null +++ b/src/zcore/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/src/zelf/.gitignore b/src/zelf/.gitignore new file mode 100644 index 0000000..61e7b92 --- /dev/null +++ b/src/zelf/.gitignore @@ -0,0 +1,38 @@ +# kdiff3 ignore +*.orig + +# maven ignore +target/ + +# eclipse ignore +.settings/ +.project +.classpath + +# idea ignore +.idea/ +*.ipr +*.iml +*.txt +*.iws + +# temp ignore +*.log +*.cache +*.diff +*.patch +*.tmp + +# system ignore +.DS_Store +Thumbs.db + +# package ignore (optional) +# *.jar +# *.war +# *.zip +# *.tar +# *.tar.gz + +# linux +.directory diff --git a/src/zelf/assert/ELF_FORMAT.jpg b/src/zelf/assert/ELF_FORMAT.jpg new file mode 100644 index 0000000..00f68ed Binary files /dev/null and b/src/zelf/assert/ELF_FORMAT.jpg differ diff --git a/src/zelf/assert/file_bin_hex.jpeg b/src/zelf/assert/file_bin_hex.jpeg new file mode 100644 index 0000000..e91f4fb Binary files /dev/null and b/src/zelf/assert/file_bin_hex.jpeg differ diff --git a/src/zelf/file/main.cpp.obj.id0 b/src/zelf/file/main.cpp.obj.id0 new file mode 100644 index 0000000..5ccb83a Binary files /dev/null and b/src/zelf/file/main.cpp.obj.id0 differ diff --git a/src/zelf/file/main.cpp.obj.id1 b/src/zelf/file/main.cpp.obj.id1 new file mode 100644 index 0000000..e69de29 diff --git a/src/zelf/file/main.cpp.obj.nam b/src/zelf/file/main.cpp.obj.nam new file mode 100644 index 0000000..e69de29 diff --git a/src/zelf/file/zasm.exe.i64 b/src/zelf/file/zasm.exe.i64 new file mode 100644 index 0000000..8223162 Binary files /dev/null and b/src/zelf/file/zasm.exe.i64 differ diff --git a/src/zelf/src/ElfFileParser.cpp b/src/zelf/src/ElfFileParser.cpp new file mode 100644 index 0000000..7d028e1 --- /dev/null +++ b/src/zelf/src/ElfFileParser.cpp @@ -0,0 +1,17 @@ +// ElfFileParser.cpp : Defines the entry point for the application. +// + +#include +#include "ElfParser.h" + +using namespace std; + +int main() +{ + cout << "开始解析:" << endl; + ElfParser elf_parser(R"(file/main.cpp.obj)"); + // ElfParser elf_parser(R"(..\..\..\file\arm64-v8a\libfoo.so)"); + elf_parser.parse(); + cout << "\n解析完毕!" << endl; + return 0; +} diff --git a/src/zelf/src/ElfParser.cpp b/src/zelf/src/ElfParser.cpp new file mode 100644 index 0000000..f61f1e3 --- /dev/null +++ b/src/zelf/src/ElfParser.cpp @@ -0,0 +1,793 @@ +#include "ElfParser.h" + +#include +#include + + +#include "type/elf.h" +#include "util/Printer.h" + +ElfParser::ElfParser() : ElfParser(nullptr) {} + +ElfParser::ElfParser(char const* elf_file) +{ + this->elf_file_ = nullptr; + this->elf_bit_ = 0; + this->elf_header32_ = Elf32_Ehdr(); + this->elf_header64_ = Elf64_Ehdr(); + + this->program_header32_list_ = nullptr; + this->program_header64_list_ = nullptr; + + this->section_header32_list_ = nullptr; + this->section_header64_list_ = nullptr; + + this->symbol32_list_ = nullptr; + this->symbol64_list_ = nullptr; + + this->string_table_ = nullptr; + this->symbol_string_table_ = nullptr; + + this->relocation32_list_ = nullptr; + this->relocation64_list_ = nullptr; + + if (elf_file == nullptr) + return; + +// const auto f = fopen_s(&this->elf_file_, elf_file, "rb"); + this->elf_file_ = fopen(elf_file, "rb"); + printf("构造函数open elf file: %s\n\n", elf_file); + if (this->elf_file_ == nullptr) + printf("构造函数open elf file error: %s\n", elf_file); +} + +ElfParser::~ElfParser() +{ + printf("\n>>>>>>>>>>>> release <<<<<<<<<<<<\n\n"); + + if (this->elf_file_ != nullptr) { + printf("close elf file.\n"); + fclose(this->elf_file_); + } + + if (this->section_header32_list_ != nullptr) + { + printf("delete section header 32 array.\n"); + delete[] this->section_header32_list_; + this->section_header32_list_ = nullptr; + } + + if (this->section_header64_list_ != nullptr) + { + printf("delete section header 64 array.\n"); + delete[] this->section_header64_list_; + this->section_header64_list_ = nullptr; + } + + if (this->program_header32_list_ != nullptr) + { + printf("delete program header 32 array.\n"); + delete[] this->program_header32_list_; + this->program_header32_list_ = nullptr; + } + + if (this->program_header64_list_ != nullptr) + { + printf("delete program header 64 array.\n"); + delete[] this->program_header64_list_; + this->program_header64_list_ = nullptr; + } + + if (this->string_table_ != nullptr) + { + printf("delete string table.\n"); + delete[] this->string_table_; + this->string_table_ = nullptr; + } + + if (this->symbol_string_table_ != nullptr) + { + printf("delete symbol string table.\n"); + delete[] this->symbol_string_table_; + this->symbol_string_table_ = nullptr; + } + + if (this->symbol32_list_ != nullptr) + { + printf("delete symbol 32 list.\n"); + delete[] this->symbol32_list_; + this->symbol32_list_ = nullptr; + } + + if (this->symbol64_list_ != nullptr) + { + printf("delete symbol 64 list.\n"); + delete[] this->symbol64_list_; + this->symbol64_list_ = nullptr; + } + + if (this->relocation32_list_ != nullptr) + { + printf("delete relocation 32 list.\n"); + delete[] this->relocation32_list_; + this->relocation32_list_ = nullptr; + } + + if (this->relocation64_list_ != nullptr) + { + printf("delete relocation 64 list.\n"); + delete[] this->relocation64_list_; + this->relocation64_list_ = nullptr; + } +} + + +void ElfParser::parse() +{ + printf(">>>>>>>>>>>> parse elf header <<<<<<<<<<<<\n\n"); + uint8_t bit; + if (!check_elf()) { + printf("it is not a elf file.\n"); + return; + } + + parse_elf_header(); + parse_section_header_list(); + parse_string_table(); + print_section_header_list(); + parse_symbol_string_table(); + parse_program_header_list(); + parse_section_list(); +} + +template +void print_elf_header(T* header, const uint8_t bit) +{ + printf("ident: \t\t"); + Printer::print_char_array(header->e_ident, 16); + printf("type: \t\t%u\n", header->e_type); + printf("machine: \t%u\n", header->e_machine); + printf("version: \t%u\n", header->e_version); + if (bit == 32) + { + printf("entry: \t\t%u\n", header->e_entry); + printf("phoff: \t\t%u\n", header->e_phoff); + printf("shoff: \t\t%u\n", header->e_shoff); + } + else // bit == 64 + { + printf("entry: \t\t%llu\n", header->e_entry); + printf("phoff: \t\t%llu\n", header->e_phoff); + printf("shoff: \t\t%llu\n", header->e_shoff); + } + + printf("flags: \t\t0x%x\n", header->e_flags); + printf("ehsize: \t%u\n", header->e_ehsize); + printf("phentsize: \t%u\n", header->e_phentsize); + printf("phnum: \t\t%u\n", header->e_phnum); + printf("shentsize: \t%u\n", header->e_shentsize); + printf("shnum: \t\t%u\n", header->e_shnum); + printf("shstrndx: \t%u\n", header->e_shstrndx); +} + +bool ElfParser::check_elf() +{ + unsigned char elf_ident[16] = { 0 }; + if (0 == fread(elf_ident, sizeof(char), 16, this->elf_file_)) + { + printf("check elf error: read error"); + return false; + } + + if (memcmp(elf_ident, ElfMagic, strlen(ElfMagic)) != 0) + return false; + + char elf_type[10] = "ERROR"; + switch (elf_ident[4]) + { + case ELFCLASSNONE: + strcpy(elf_type, "invalid"); + break; + case ELFCLASS32: + strcpy(elf_type, "ELF32"); + this->elf_bit_ = 32; + break; + case ELFCLASS64: + strcpy(elf_type, "ELF64"); + this->elf_bit_ = 64; + break; + default: + break; + } + + printf("Class: \t\t%s\n", elf_type); + + char elf_order[15] = "ERROR"; + switch (elf_ident[5]) + { + case ELFDATANONE: + strcpy(elf_order, "invalid"); + break; + case ELFDATA2LSB: + strcpy(elf_order, "little endian"); + break; + case ELFDATA2MSB: + strcpy(elf_order, "big endian"); + break; + default: + break; + } + + printf("Order: \t\t%s\n", elf_order); + + return true; +} + +void ElfParser::parse_elf_header() +{ + if (0 != fseek(this->elf_file_, 0, 0)) + { + printf("#parse_elf_header - seek file error.\n"); + return; + } + + void* elf_header = nullptr; + size_t elf_header_size = 0; + if (this->elf_bit_ == 32) + { + elf_header = &this->elf_header32_; + elf_header_size = sizeof(Elf32_Ehdr); + } + else // this->elf_bit_ == 64 + { + elf_header = &this->elf_header64_; + elf_header_size = sizeof(Elf64_Ehdr); + } + + if (0 == fread(elf_header, elf_header_size, 1, this->elf_file_)) + { + printf("parse elf header%d error.\n", this->elf_bit_); + return; + } + + if (this->elf_bit_ == 32) + print_elf_header(&this->elf_header32_, 32); + else // this->elf_bit_ == 64 + print_elf_header(&this->elf_header64_, 64); +} + + +// todo: pretty print +template +static void print_section_header(T* header, const uint8_t bit) +{ +#ifdef _PRINT_SECTION_HEADER_LIST_ + printf("sh_name: \t%u\n", header->sh_name); + printf("sh_type: \t0x%x\n", header->sh_type); + printf("sh_link: \t%u\n", header->sh_link); + printf("sh_info: \t%u\n", header->sh_info); + + if (bit == 32) + { + printf("sh_flags: \t%u\n", header->sh_flags); + printf("sh_offset: \t%u\n", header->sh_offset); + printf("sh_size: \t%u\n", header->sh_size); + printf("sh_addr: \t%u\n", header->sh_addr); + printf("sh_addralign: \t%u\n", header->sh_addralign); + printf("sh_entsize: \t%u\n", header->sh_entsize); + } + else // bit == 64 + { + printf("sh_flags: \t%llu\n", header->sh_flags); + printf("sh_offset: \t%llu\n", header->sh_offset); + printf("sh_size: \t%llu\n", header->sh_size); + printf("sh_addr: \t%llu\n", header->sh_addr); + printf("sh_addralign: \t%llu\n", header->sh_addralign); + printf("sh_entsize: %llu\n", header->sh_entsize); + } +#endif // _PRINT_PROGRAM_HEADER_LIST_ +} + +void ElfParser::parse_section_header_list() +{ + printf("\n>>>>>>>>>>>> parse section header list <<<<<<<<<<<<\n\n"); + + long section_header_offset = 0; + size_t section_header_count = 0; + size_t section_header_size = 0; + void* section_header_list = nullptr; + + if (this->elf_bit_ == 32) + { + section_header_offset = this->elf_header32_.e_shoff; + section_header_count = this->elf_header32_.e_shnum; + section_header_size = sizeof(Elf32_Shdr); + + this->section_header32_list_ = new Elf32_Shdr[section_header_count]; + section_header_list = this->section_header32_list_; + + printf("section header offset: \t%u\n", this->elf_header32_.e_shoff); + printf("section header size: \t%u\n", this->elf_header32_.e_shnum); + } + else // this->elf_bit_ == 64 + { + section_header_offset = this->elf_header64_.e_shoff; + section_header_count = this->elf_header64_.e_shnum; + section_header_size = sizeof(Elf64_Shdr); + + this->section_header64_list_ = new Elf64_Shdr[section_header_count]; + section_header_list = this->section_header64_list_; + + printf("section header offset: \t%llu\n", this->elf_header64_.e_shoff); + printf("section header size: \t%u\n", this->elf_header64_.e_shnum); + } + + if (0 != fseek(this->elf_file_, section_header_offset, 0)) + { + printf("#parse_section_header - seek file error.\n"); + return; + } + + if (0 == fread(section_header_list, section_header_size, section_header_count, this->elf_file_)) + { + printf("parse section header%d error.\n", this->elf_bit_); + return; + } +} + +void ElfParser::parse_string_table() +{ + printf("\n>>>>>>>>>>>> parse string table <<<<<<<<<<<<\n\n"); + // for .shstrtab; + + size_t offset; + size_t size; + if (this->elf_bit_ == 32) + { + // 字符串表下标 + const auto str_table_index = this->elf_header32_.e_shstrndx; + const auto& section_header = this->section_header32_list_[str_table_index]; + offset = section_header.sh_offset; + size = section_header.sh_size; + } + else // this->elf_bit_ == 64 + { + const auto str_table_index = this->elf_header64_.e_shstrndx; + const auto& section_header = this->section_header64_list_[str_table_index]; + offset = section_header.sh_offset; + size = section_header.sh_size; + } + + if (0 != fseek(this->elf_file_, offset, 0)) + { + printf("#parse_string_table - seek file error.\n"); + return; + } + + this->string_table_ = new char[size]; + if (0 == fread(this->string_table_, size, 1, this->elf_file_)) + { + printf("parse string table%d error.\n", this->elf_bit_); + return; + } + + size_t string_count = 0; + for (size_t i = 0; i < size; i++) + { + if (this->string_table_[i] == 0 && i != (size - 1)) + { + const auto off = i + 1; + const auto* str = get_string_from_string_table(off); + const auto len = strlen(str); + + printf("str[%llu] \tlen: %llu, s: %s\n", off, len, str); + + string_count++; + } + } + + printf("string count: %llu\n", string_count); +} + +void ElfParser::print_section_header_list() const +{ +#ifdef _PRINT_SECTION_HEADER_LIST_ + size_t section_header_count = 0; + + if (this->elf_bit_ == 32) + section_header_count = this->elf_header32_.e_shnum; + else // this->elf_bit_ == 64 + section_header_count = this->elf_header64_.e_shnum; + + for (size_t i = 0; i < section_header_count; i++) + { + printf("\n>>>>>>>>>>>> parse section header <<<<<<<<<<<<\n\n"); + + printf("index: \t\t%llu\n", i); + + if (this->elf_bit_ == 32) + { + printf("name: \t\t%s\n\n", get_string_from_string_table(this->section_header32_list_[i].sh_name)); + print_section_header(&this->section_header32_list_[i], this->elf_bit_); + } + else // this->elf_bit_ == 64 + { + printf("name: \t\t%s\n\n", get_string_from_string_table(this->section_header64_list_[i].sh_name)); + print_section_header(&this->section_header64_list_[i], this->elf_bit_); + } + } +#endif // _PRINT_SECTION_HEADER_LIST_ +} + +void ElfParser::parse_symbol_string_table() +{ + printf("\n>>>>>>>>>>>> parse symbol string table <<<<<<<<<<<<\n\n"); + // for .dynstr + + size_t offset = 0; + size_t size = 0; + if(this->elf_bit_ == 32) + { + for (size_t i = 0; i < this->elf_header32_.e_shnum; i++) + { + auto& section_header = this->section_header32_list_[i]; + const auto* section_name = get_string_from_string_table(section_header.sh_name); + if(section_header.sh_type == SHT_STRTAB && strcmp(section_name, ".dynstr") == 0) + { + offset = section_header.sh_offset; + size = section_header.sh_size; + break; + } + } + } + else // this->elf_bit_ == 32 + { + for (size_t i = 0; i < this->elf_header64_.e_shnum; i++) + { + auto& section_header = this->section_header64_list_[i]; + const auto* section_name = get_string_from_string_table(section_header.sh_name); + if (section_header.sh_type == SHT_STRTAB && strcmp(section_name, ".dynstr") == 0) + { + offset = section_header.sh_offset; + size = section_header.sh_size; + break; + } + } + } + + if(offset == 0 || size == 0) + { + printf("error: not found section .dynstr\n"); + return; + } + + if (0 != fseek(this->elf_file_, offset, 0)) + { + printf("#parse_symbol_string_table - seek file error.\n"); + return; + } + + this->symbol_string_table_ = new char[size]; + if (0 == fread(this->symbol_string_table_, size, 1, this->elf_file_)) + { + printf("parse symbol string table%d error.\n", this->elf_bit_); + return; + } + + size_t string_count = 0; + for (size_t i = 0; i < size; i++) + { + if (this->symbol_string_table_[i] == 0 && i != (size - 1)) + { + const auto off = i + 1; + const auto* str = get_string_from_symbol_string_table(off); + const auto len = strlen(str); + + printf("str[%llu] \tlen: %llu, s: %s\n", off, len, str); + + string_count++; + } + } + + printf("string count: %llu\n", string_count); +} + +const char* ElfParser::get_string_from_string_table(const size_t offset) const +{ + return &this->string_table_[offset]; +} + + +inline const char* ElfParser::get_string_from_symbol_string_table(size_t offset) const +{ + return &this->symbol_string_table_[offset]; +} + +// todo: pretty print +template +static void print_program_header(T* header, const uint8_t bit) +{ +#ifdef _PRINT_PROGRAM_HEADER_LIST_ + printf("p_type: \t0x%x\n", header->p_type); + printf("p_flags: \t%u\n", header->p_flags); + if (bit == 32) + { + printf("p_offset: \t%u\n", header->p_offset); + printf("p_vaddr: \t%u\n", header->p_vaddr); + printf("p_paddr: \t%u\n", header->p_paddr); + printf("p_filesz: \t%u\n", header->p_filesz); + printf("p_memsz: \t%u\n", header->p_memsz); + printf("p_align: \t%u\n", header->p_align); + } + else // bit == 64 + { + printf("p_offset: \t0x%x\n", header->p_offset); + printf("p_vaddr: \t%llu\n", header->p_vaddr); + printf("p_paddr: \t%llu\n", header->p_paddr); + printf("p_filesz: \t%llu\n", header->p_filesz); + printf("p_memsz: \t%llu\n", header->p_memsz); + printf("p_align: \t%llu\n", header->p_align); + } +#endif // _PRINT_PROGRAM_HEADER_LIST_ +} + +void ElfParser::parse_program_header_list() +{ + printf("\n>>>>>>>>>>>> parse program list <<<<<<<<<<<<\n\n"); + + long program_header_list_offset = 0; + size_t program_header_count = 0; + size_t program_header_size = 0; + void* program_header_list = nullptr; + + if (this->elf_bit_ == 32) + { + program_header_list_offset = this->elf_header32_.e_phoff; + program_header_count = this->elf_header32_.e_phnum; + program_header_size = sizeof(Elf32_Phdr); + + this->program_header32_list_ = new Elf32_Phdr[program_header_count]; + program_header_list = this->program_header32_list_; + + printf("program header offset: \t%u\n", this->elf_header32_.e_phoff); + printf("program header size: \t%u\n", this->elf_header32_.e_phnum); + } + else // this->elf_bit_ == 64 + { + program_header_list_offset = this->elf_header64_.e_phoff; + program_header_count = this->elf_header64_.e_phnum; + program_header_size = sizeof(Elf64_Phdr); + + this->program_header64_list_ = new Elf64_Phdr[program_header_count]; + program_header_list = this->program_header64_list_; + + printf("program header offset: \t%llu\n", this->elf_header64_.e_phoff); + printf("program header size: \t%u\n", this->elf_header64_.e_phnum); + } + + if (0 != fseek(this->elf_file_, program_header_list_offset, 0)) + { + printf("#parse_program_header_list - seek file error.\n"); + return; + } + + if (0 == fread(program_header_list, program_header_size, program_header_count, this->elf_file_)) + { + printf("parse program header%d error.\n", this->elf_bit_); + return; + } + +#ifdef _PRINT_PROGRAM_HEADER_LIST_ + for (size_t i = 0; i < program_header_count; i++) + { + printf("\n>>>>>>>>>>>> parse program header <<<<<<<<<<<<\n\n"); + printf("index: \t\t%llu\n\n", i); + + if (this->elf_bit_ == 32) + print_program_header(&this->program_header32_list_[i], this->elf_bit_); + else // this->elf_bit_ == 64 + print_program_header(&this->program_header64_list_[i], this->elf_bit_); + } +#endif // _PRINT_PROGRAM_HEADER_LIST_ +} + +void ElfParser::parse_section_list() +{ + printf("\n>>>>>>>>>>>> parse section list <<<<<<<<<<<<\n\n"); + + size_t list_len = 0; + if (this->elf_bit_ == 32) + list_len = this->elf_header32_.e_shnum; + else // this->elf_bit_ == 64 + list_len = this->elf_header64_.e_shnum; + + if (this->elf_bit_ == 32) + { + for (size_t i = 0; i < list_len; i++) + { + auto& section_header = this->section_header32_list_[i]; + printf("parse section: %s\n", get_string_from_string_table(section_header.sh_name)); + + switch (section_header.sh_type) + { + case SHT_SYMTAB: + break; + case SHT_DYNSYM: + parse_symbol_table(section_header.sh_offset, section_header.sh_size); + break; + case SHT_REL: + parse_relocation_table(section_header.sh_offset, section_header.sh_size); + break; + default: + printf("ignored.\n"); + break; + } + } + } + else // this->elf_bit_ == 64 + { + for (size_t i = 0; i < list_len; i++) + { + auto& section_header = this->section_header64_list_[i]; + printf("parse section: %s\n", get_string_from_string_table(section_header.sh_name)); + + switch (section_header.sh_type) + { + case SHT_SYMTAB: + break; + case SHT_DYNSYM: + parse_symbol_table(section_header.sh_offset, section_header.sh_size); + break; + default: + printf("ignored.\n"); + break; + } + } + } +} + + +template +static void print_symbol(T* symbol, const uint8_t bit) +{ + if (bit == 32) + { + printf("st_name: \t%u\n", symbol->st_name); + printf("st_value: \t%u\n", symbol->st_value); + printf("st_size: \t%u\n", symbol->st_size); + printf("st_info: \t%u\n", symbol->st_info); + printf("st_other: \t%u\n", symbol->st_other); + printf("st_shndx: \t%u\n", symbol->st_shndx); + } + else // bit == 64 + { + printf("st_name: \t%llu\n", symbol->st_name); + printf("st_value: \t%llu\n", symbol->st_value); + printf("st_size: \t%llu\n", symbol->st_size); + printf("st_info: \t%llu\n", symbol->st_info); + printf("st_other: \t%llu\n", symbol->st_other); + printf("st_shndx: \t%llu\n", symbol->st_shndx); + } +} + +void ElfParser::parse_symbol_table(const long offset, const size_t size) +{ + printf("\n>>>>>>>>>>>> parse symbol table <<<<<<<<<<<<\n\n"); + + if (0 != fseek(this->elf_file_, offset, 0)) + { + printf("#parse_symbol_table - seek file error.\n"); + return; + } + + size_t sym_size = 0; + size_t sym_count = 0; + void* symbol_buffer = nullptr; + if (this->elf_bit_ == 32) + { + sym_size = sizeof(Elf32_Sym); + sym_count = size / sym_size; + + this->symbol32_list_ = new Elf32_Sym[sym_count]; + symbol_buffer = this->symbol32_list_; + } + else // this->elf_bit_ == 64 + { + sym_size = sizeof(Elf64_Sym); + sym_count = size / sym_size; + + this->symbol64_list_ = new Elf64_Sym[sym_count]; + symbol_buffer = this->symbol64_list_; + } + + printf("symbol count: %llu\n", sym_count); + + if (0 == fread(symbol_buffer, sym_size, sym_count, this->elf_file_)) + { + printf("parse symbol table%d error.\n", this->elf_bit_); + return; + } + +#ifdef _PRINT_SYMBOL_TABLE_ + for (size_t i = 0; i < sym_count; i++) + { + printf("\n>>>>>>>>>>>> parse symbol <<<<<<<<<<<<\n\n"); + + printf("index: %llu\n", i); + + if (this->elf_bit_ == 32) + { + auto& symbol = this->symbol32_list_[i]; + printf("symbol name: %s\n\n", get_string_from_symbol_string_table(symbol.st_name)); + print_symbol(&symbol, this->elf_bit_); + } + else // this-elf_bit_ == 64 + { + auto& symbol = this->symbol64_list_[i]; + printf("symbol name: %s\n\n", get_string_from_symbol_string_table(symbol.st_name)); + print_symbol(&symbol, this->elf_bit_); + } + } +#endif // _PRINT_SYMBOL_TABLE_ +} + +void ElfParser::parse_relocation_table(const long offset, const size_t size) +{ + printf("\n>>>>>>>>>>>> parse relocation table <<<<<<<<<<<<\n\n"); + + if (0 != fseek(this->elf_file_, offset, 0)) + { + printf("#parse_relocation_table - seek file error.\n"); + return; + } + + size_t rel_size = 0; + size_t rel_count = 0; + void* rel_buffer = nullptr; + if (this->elf_bit_ == 32) + { + rel_size = sizeof(Elf32_Rel); + rel_count = size / rel_size; + + this->relocation32_list_ = new Elf32_Rel[rel_count]; + rel_buffer = this->relocation32_list_; + } + else // this->elf_bit_ == 64 + { + rel_size = sizeof(Elf64_Rel); + rel_count = size / rel_size; + + this->relocation64_list_ = new Elf64_Rel[rel_count]; + rel_buffer = this->relocation64_list_; + } + + printf("relocation entries count: %llu\n", rel_count); + + if (0 == fread(rel_buffer, rel_size, rel_count, this->elf_file_)) + { + printf("parse relocation table%d error.\n", this->elf_bit_); + return; + } + +#ifdef _PRINT_RELOCATION_TABLE + for (size_t i = 0; i < rel_count; i++) + { + printf("\n>>>>>>>>>>>> parse relocation entry <<<<<<<<<<<<\n\n"); + + printf("index: %llu\n\n", i); + + if (this->elf_bit_ == 32) + { + auto& relocation = this->relocation32_list_[i]; + printf("r_offset: \t%u\n", relocation.r_offset); + printf("r_info: \t%u\n", relocation.r_info); + } + else // this-elf_bit_ == 64 + { + auto& relocation = this->relocation64_list_[i]; + printf("r_offset: \t%llu\n", relocation.r_offset); + printf("r_info: \t%llu\n", relocation.r_info); + } + } +#endif // _PRINT_RELOCATION_TABLE +} diff --git a/src/zelf/src/ElfParser.h b/src/zelf/src/ElfParser.h new file mode 100644 index 0000000..5f53ab8 --- /dev/null +++ b/src/zelf/src/ElfParser.h @@ -0,0 +1,50 @@ +#ifndef ELF_PARSER_H +#define ELF_PARSER_H +#include +#include "type/elf.h" + +class ElfParser +{ +public: + ElfParser(); + explicit ElfParser(char const* elf_file); + ~ElfParser(); + void parse(); +private: + FILE* elf_file_; + uint8_t elf_bit_; + + Elf32_Ehdr elf_header32_{}; + Elf64_Ehdr elf_header64_{}; + + Elf32_Phdr* program_header32_list_; + Elf64_Phdr* program_header64_list_; + + Elf32_Shdr* section_header32_list_; + Elf64_Shdr* section_header64_list_; + + char* string_table_; + char* symbol_string_table_; + + Elf32_Sym* symbol32_list_; + Elf64_Sym* symbol64_list_; + + Elf32_Rel* relocation32_list_; + Elf64_Rel* relocation64_list_; + + bool check_elf(); + void parse_elf_header(); + void parse_section_header_list(); + void parse_string_table(); + void print_section_header_list() const; + void parse_symbol_string_table(); + void parse_program_header_list(); + void parse_section_list(); + void parse_symbol_table(long offset, size_t size); + void parse_relocation_table(long offset, size_t size); + + const char* get_string_from_string_table(size_t offset) const; + const char* get_string_from_symbol_string_table(size_t offset) const; +}; + +#endif // ELF_PARSER_H diff --git a/src/zelf/src/type/elf.h b/src/zelf/src/type/elf.h new file mode 100644 index 0000000..c5737eb --- /dev/null +++ b/src/zelf/src/type/elf.h @@ -0,0 +1,549 @@ +#ifndef ELF_H +#define ELF_H + +#include + +typedef uint32_t Elf32_Addr; // Program address +typedef uint32_t Elf32_Off; // File offset +typedef uint16_t Elf32_Half; +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; + +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; +typedef uint16_t Elf64_Half; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +static constexpr char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' }; + +// e_ident size and indices. +enum { + EI_MAG0 = 0, // 文件标识索引 + EI_MAG1 = 1, // 文件标识索引 + EI_MAG2 = 2, // 文件标识索引 + EI_MAG3 = 3, // 文件标识索引 + EI_CLASS = 4, // File class. + EI_DATA = 5, // Data encoding. + EI_VERSION = 6, // File version. + EI_OSABI = 7, // OS/ABI identification. + EI_ABIVERSION = 8, // ABI version. + EI_PAD = 9, // Start of padding bytes. + EI_NIDENT = 16 // Number of bytes in e_ident. +}; + +constexpr char ELFMAG0 = ElfMagic[EI_MAG0]; +constexpr char ELFMAG1 = ElfMagic[EI_MAG1]; +constexpr char ELFMAG2 = ElfMagic[EI_MAG2]; +constexpr char ELFMAG3 = ElfMagic[EI_MAG3]; +constexpr char ELFMAG[] = "\177ELF"; +constexpr int SELFMAG = 4; +constexpr int NT_PRSTATUS = 1; + +// Elf 文件头 +struct Elf32_Ehdr { + unsigned char e_ident[EI_NIDENT]; // 文件标识 + Elf32_Half e_type; // 文件类型 + Elf32_Half e_machine; // ELF 文件的 CPU 平台属性,相关常量以 EM_ 开头 + Elf32_Word e_version; // ELF 版本号,一般为常数 1 + Elf32_Addr e_entry; // 入口地址,规定 ELF 程序的入口虚拟地址,操作系统在加载完该程序后从这个地址开始执行进程的指令 + Elf32_Off e_phoff; // Program header 表的文件偏移字节 + Elf32_Off e_shoff; // 段表在文件中的偏移 + Elf32_Word e_flags; // LF 标志位,用来标识一些 ELF 文件平台相关的属性。相关常量格式一般为 EF_machine_flag,machine 为平台,flag 为标志 + Elf32_Half e_ehsize; // ELF 文件头本身的大小 + Elf32_Half e_phentsize; // Program header 表的大小 + Elf32_Half e_phnum; // Program header 表的数量 + Elf32_Half e_shentsize; // 段表描述符的大小,这个一般等于一节 + Elf32_Half e_shnum; // 段表描述符数量。这个值等于 ELF 文件中拥有段的数量 + Elf32_Half e_shstrndx; // 段表字符串表所在的段在段表中的下标 +}; + + +struct Elf64_Ehdr { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +}; + +// 程序头表,表示装载后的 Segment 结构 +struct Elf32_Phdr { + Elf32_Word p_type; // 段类型 + Elf32_Off p_offset; // 段在文件中的偏移 + Elf32_Addr p_vaddr; // 段的第一个字节在虚拟地址空间的起始位置,整个程序表头中 + Elf32_Addr p_paddr; // 段的物理装载地址,即 LMA(Load Memory Address),一般情况下 p_paddr 和 p_vaddr 是相同的 + Elf32_Word p_filesz; // 段在 ELF 文件中所占空间的长度,可能为 0 + Elf32_Word p_memsz; // 段在进程虚拟空间中所占空间的长度,可能为 0 + Elf32_Word p_flags; // 段的权限属性,比如可读 "R",可写 "W" 和可执行 "X" + Elf32_Word p_align; // 段的对齐属性,实际对齐字节等于 2 的 p_align 次方 +}; + + +struct Elf64_Phdr { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +}; + +// File types +enum { + ET_NONE = 0, // No file type + ET_REL = 1, // Relocatable file + ET_EXEC = 2, // Executable file + ET_DYN = 3, // Shared object file + ET_CORE = 4, // Core file + ET_LOPROC = 0xff00, // Beginning of processor-specific codes + ET_HIPROC = 0xffff // Processor-specific +}; + +// Versioning +enum { + EV_NONE = 0, + EV_CURRENT = 1 +}; + +// Machine architectures +enum { + EM_NONE = 0, // No machine + EM_M32 = 1, // AT&T WE 32100 + EM_SPARC = 2, // SPARC + EM_386 = 3, // Intel 386 + EM_68K = 4, // Motorola 68000 + EM_88K = 5, // Motorola 88000 + EM_486 = 6, // Intel 486 (deprecated) + EM_860 = 7, // Intel 80860 + EM_MIPS = 8, // MIPS R3000 + EM_S370 = 9, // IBM System/370 + EM_MIPS_RS3_LE = 10, // MIPS RS3000 Little-endian + EM_PARISC = 15, // Hewlett-Packard PA-RISC + EM_VPP500 = 17, // Fujitsu VPP500 + EM_SPARC32PLUS = 18, // Enhanced instruction set SPARC + EM_960 = 19, // Intel 80960 + EM_PPC = 20, // PowerPC + EM_PPC64 = 21, // PowerPC64 + EM_S390 = 22, // IBM System/390 + EM_SPU = 23, // IBM SPU/SPC + EM_V800 = 36, // NEC V800 + EM_FR20 = 37, // Fujitsu FR20 + EM_RH32 = 38, // TRW RH-32 + EM_RCE = 39, // Motorola RCE + EM_ARM = 40, // ARM + EM_ALPHA = 41, // DEC Alpha + EM_SH = 42, // Hitachi SH + EM_SPARCV9 = 43, // SPARC V9 + EM_TRICORE = 44, // Siemens TriCore + EM_ARC = 45, // Argonaut RISC Core + EM_H8_300 = 46, // Hitachi H8/300 + EM_H8_300H = 47, // Hitachi H8/300H + EM_H8S = 48, // Hitachi H8S + EM_H8_500 = 49, // Hitachi H8/500 + EM_IA_64 = 50, // Intel IA-64 processor architecture + EM_MIPS_X = 51, // Stanford MIPS-X + EM_COLDFIRE = 52, // Motorola ColdFire + EM_68HC12 = 53, // Motorola M68HC12 + EM_MMA = 54, // Fujitsu MMA Multimedia Accelerator + EM_PCP = 55, // Siemens PCP + EM_NCPU = 56, // Sony nCPU embedded RISC processor + EM_NDR1 = 57, // Denso NDR1 microprocessor + EM_STARCORE = 58, // Motorola Star*Core processor + EM_ME16 = 59, // Toyota ME16 processor + EM_ST100 = 60, // STMicroelectronics ST100 processor + EM_TINYJ = 61, // Advanced Logic Corp. TinyJ embedded processor family + EM_X86_64 = 62, // AMD x86-64 architecture + EM_PDSP = 63, // Sony DSP Processor + EM_PDP10 = 64, // Digital Equipment Corp. PDP-10 + EM_PDP11 = 65, // Digital Equipment Corp. PDP-11 + EM_FX66 = 66, // Siemens FX66 microcontroller + EM_ST9PLUS = 67, // STMicroelectronics ST9+ 8/16 bit microcontroller + EM_ST7 = 68, // STMicroelectronics ST7 8-bit microcontroller + EM_68HC16 = 69, // Motorola MC68HC16 Microcontroller + EM_68HC11 = 70, // Motorola MC68HC11 Microcontroller + EM_68HC08 = 71, // Motorola MC68HC08 Microcontroller + EM_68HC05 = 72, // Motorola MC68HC05 Microcontroller + EM_SVX = 73, // Silicon Graphics SVx + EM_ST19 = 74, // STMicroelectronics ST19 8-bit microcontroller + EM_VAX = 75, // Digital VAX + EM_CRIS = 76, // Axis Communications 32-bit embedded processor + EM_JAVELIN = 77, // Infineon Technologies 32-bit embedded processor + EM_FIREPATH = 78, // Element 14 64-bit DSP Processor + EM_ZSP = 79, // LSI Logic 16-bit DSP Processor + EM_MMIX = 80, // Donald Knuth's educational 64-bit processor + EM_HUANY = 81, // Harvard University machine-independent object files + EM_PRISM = 82, // SiTera Prism + EM_AVR = 83, // Atmel AVR 8-bit microcontroller + EM_FR30 = 84, // Fujitsu FR30 + EM_D10V = 85, // Mitsubishi D10V + EM_D30V = 86, // Mitsubishi D30V + EM_V850 = 87, // NEC v850 + EM_M32R = 88, // Mitsubishi M32R + EM_MN10300 = 89, // Matsushita MN10300 + EM_MN10200 = 90, // Matsushita MN10200 + EM_PJ = 91, // picoJava + EM_OPENRISC = 92, // OpenRISC 32-bit embedded processor + EM_ARC_COMPACT = 93, // ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) + EM_XTENSA = 94, // Tensilica Xtensa Architecture + EM_VIDEOCORE = 95, // Alphamosaic VideoCore processor + EM_TMM_GPP = 96, // Thompson Multimedia General Purpose Processor + EM_NS32K = 97, // National Semiconductor 32000 series + EM_TPC = 98, // Tenor Network TPC processor + EM_SNP1K = 99, // Trebia SNP 1000 processor + EM_ST200 = 100, // STMicroelectronics (www.st.com) ST200 + EM_IP2K = 101, // Ubicom IP2xxx microcontroller family + EM_MAX = 102, // MAX Processor + EM_CR = 103, // National Semiconductor CompactRISC microprocessor + EM_F2MC16 = 104, // Fujitsu F2MC16 + EM_MSP430 = 105, // Texas Instruments embedded microcontroller msp430 + EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP) processor + EM_SE_C33 = 107, // S1C33 Family of Seiko Epson processors + EM_SEP = 108, // Sharp embedded microprocessor + EM_ARCA = 109, // Arca RISC Microprocessor + EM_UNICORE = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University + EM_EXCESS = 111, // eXcess: 16/32/64-bit configurable embedded CPU + EM_DXP = 112, // Icera Semiconductor Inc. Deep Execution Processor + EM_ALTERA_NIOS2 = 113, // Altera Nios II soft-core processor + EM_CRX = 114, // National Semiconductor CompactRISC CRX + EM_XGATE = 115, // Motorola XGATE embedded processor + EM_C166 = 116, // Infineon C16x/XC16x processor + EM_M16C = 117, // Renesas M16C series microprocessors + EM_DSPIC30F = 118, // Microchip Technology dsPIC30F Digital Signal Controller + EM_CE = 119, // Freescale Communication Engine RISC core + EM_M32C = 120, // Renesas M32C series microprocessors + EM_TSK3000 = 131, // Altium TSK3000 core + EM_RS08 = 132, // Freescale RS08 embedded processor + EM_SHARC = 133, // Analog Devices SHARC family of 32-bit DSP processors + EM_ECOG2 = 134, // Cyan Technology eCOG2 microprocessor + EM_SCORE7 = 135, // Sunplus S+core7 RISC processor + EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP Processor + EM_VIDEOCORE3 = 137, // Broadcom VideoCore III processor + EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture + EM_SE_C17 = 139, // Seiko Epson C17 family + EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP family + EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP family + EM_TI_C5500 = 142, // The Texas Instruments TMS320C55x DSP family + EM_MMDSP_PLUS = 160, // STMicroelectronics 64bit VLIW Data Signal Processor + EM_CYPRESS_M8C = 161, // Cypress M8C microprocessor + EM_R32C = 162, // Renesas R32C series microprocessors + EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture family + EM_HEXAGON = 164, // Qualcomm Hexagon processor + EM_8051 = 165, // Intel 8051 and variants + EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable and extensible RISC processors + EM_NDS32 = 167, // Andes Technology compact code size embedded RISC processor family + EM_ECOG1 = 168, // Cyan Technology eCOG1X family + EM_ECOG1X = 168, // Cyan Technology eCOG1X family + EM_MAXQ30 = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers + EM_XIMO16 = 170, // New Japan Radio (NJR) 16-bit DSP Processor + EM_MANIK = 171, // M2000 Reconfigurable RISC Microprocessor + EM_CRAYNV2 = 172, // Cray Inc. NV2 vector architecture + EM_RX = 173, // Renesas RX family + EM_METAG = 174, // Imagination Technologies META processor architecture + EM_MCST_ELBRUS = 175, // MCST Elbrus general purpose hardware architecture + EM_ECOG16 = 176, // Cyan Technology eCOG16 family + EM_CR16 = 177, // National Semiconductor CompactRISC CR16 16-bit microprocessor + EM_ETPU = 178, // Freescale Extended Time Processing Unit + EM_SLE9X = 179, // Infineon Technologies SLE9X core + EM_L10M = 180, // Intel L10M + EM_K10M = 181, // Intel K10M + EM_AARCH64 = 183, // ARM AArch64 + EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family + EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller + EM_TILE64 = 187, // Tilera TILE64 multicore architecture family + EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family + EM_CUDA = 190, // NVIDIA CUDA architecture + EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family + EM_CLOUDSHIELD = 192, // CloudShield architecture family + EM_COREA_1S = 193, // KIPO-KAIST Core-A 1st generation processor family + EM_COREA_2ND = 194, // KIPO-KAIST Core-A 2nd generation processor family + EM_ARC_COMPACT2 = 195, // Synopsys ARCompact V2 + EM_OPEN8 = 196, // Open8 8-bit RISC soft processor core + EM_RL78 = 197, // Renesas RL78 family + EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor + EM_78KOR = 199, // Renesas 78KOR family + EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC) +}; + +// Object file classes. +enum { + ELFCLASSNONE = 0, + ELFCLASS32 = 1, // 32-bit object file + ELFCLASS64 = 2 // 64-bit object file +}; + +// Object file byte orderings. +enum { + ELFDATANONE = 0, // Invalid data encoding. + ELFDATA2LSB = 1, // Little-endian object file + ELFDATA2MSB = 2 // Big-endian object file +}; + +// OS ABI identification. +enum { + ELFOSABI_NONE = 0, // UNIX System V ABI + ELFOSABI_HPUX = 1, // HP-UX operating system + ELFOSABI_NETBSD = 2, // NetBSD + ELFOSABI_GNU = 3, // GNU/Linux + ELFOSABI_LINUX = 3, // Historical alias for ELFOSABI_GNU. + ELFOSABI_HURD = 4, // GNU/Hurd + ELFOSABI_SOLARIS = 6, // Solaris + ELFOSABI_AIX = 7, // AIX + ELFOSABI_IRIX = 8, // IRIX + ELFOSABI_FREEBSD = 9, // FreeBSD + ELFOSABI_TRU64 = 10, // TRU64 UNIX + ELFOSABI_MODESTO = 11, // Novell Modesto + ELFOSABI_OPENBSD = 12, // OpenBSD + ELFOSABI_OPENVMS = 13, // OpenVMS + ELFOSABI_NSK = 14, // Hewlett-Packard Non-Stop Kernel + ELFOSABI_AROS = 15, // AROS + ELFOSABI_FENIXOS = 16, // FenixOS + ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000 + ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000 + ELFOSABI_ARM = 97, // ARM + ELFOSABI_STANDALONE = 255 // Standalone (embedded) application +}; + + +// 段表 +struct Elf32_Shdr { + Elf32_Word sh_name; // 段名,位于 .shstrtab 的字符串表。sh_name 是段名在其中的偏移 + Elf32_Word sh_type; // 段类型(SHT_*) + Elf32_Word sh_flags; // 段标志位(SHF_*) + Elf32_Addr sh_addr; // 段的虚拟地址,前提是该段可被加载,否则为 0 + Elf32_Off sh_offset; // 段偏移,前提是该段存在于文件中,否则无意义 + Elf32_Word sh_size; // 段的长度 + Elf32_Word sh_link; // 段的链接信息 + Elf32_Word sh_info; // 段的额外信息 + Elf32_Word sh_addralign; // 段地址对齐 + Elf32_Word sh_entsize; // 项的长度 +}; + + +struct Elf64_Shdr { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +}; + +// Special section indices. +enum { + SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless + SHN_LORESERVE = 0xff00, // Lowest reserved index + SHN_LOPROC = 0xff00, // Lowest processor-specific index + SHN_HIPROC = 0xff1f, // Highest processor-specific index + SHN_LOOS = 0xff20, // Lowest operating system-specific index + SHN_HIOS = 0xff3f, // Highest operating system-specific index + SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation + SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables + SHN_XINDEX = 0xffff, // Mark that the index is >= SHN_LORESERVE + SHN_HIRESERVE = 0xffff // Highest reserved index +}; + + // Section types. + enum : unsigned { + SHT_NULL = 0, // No associated section (inactive entry). + SHT_PROGBITS = 1, // Program-defined contents. + SHT_SYMTAB = 2, // Symbol table. + SHT_STRTAB = 3, // String table. + SHT_RELA = 4, // Relocation entries; explicit addends. + SHT_HASH = 5, // Symbol hash table. + SHT_DYNAMIC = 6, // Information for dynamic linking. + SHT_NOTE = 7, // Information about the file. + SHT_NOBITS = 8, // Data occupies no space in the file. + SHT_REL = 9, // Relocation entries; no explicit addends. + SHT_SHLIB = 10, // Reserved. + SHT_DYNSYM = 11, // Symbol table. + SHT_INIT_ARRAY = 14, // Pointers to initialization functions. + SHT_FINI_ARRAY = 15, // Pointers to termination functions. + SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions. + SHT_GROUP = 17, // Section group. + SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. + SHT_LOOS = 0x60000000, // Lowest operating system-specific type. + SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes. + SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table. + SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. + SHT_GNU_verneed = 0x6ffffffe, // GNU version references. + SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table. + SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. + SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type. + SHT_ARM_EXIDX = 0x70000001U, // Exception Index table + SHT_ARM_PREEMPTMAP = 0x70000002U, // BPABI DLL dynamic linking pre-emption map + SHT_ARM_ATTRIBUTES = 0x70000003U, // Object file compatibility attributes + SHT_ARM_DEBUGOVERLAY = 0x70000004U, + SHT_ARM_OVERLAYSECTION = 0x70000005U, + SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in this section based on their sizes + SHT_X86_64_UNWIND = 0x70000001, // Unwind information + SHT_MIPS_REGINFO = 0x70000006, // Register usage information + SHT_MIPS_OPTIONS = 0x7000000d, // General options + SHT_MIPS_ABIFLAGS = 0x7000002a, // Abiflags options + SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type. + SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. + SHT_HIUSER = 0xffffffff // Highest type reserved for applications. + }; + + // Section flags. + enum : unsigned { + // Section data should be writable during execution. + SHF_WRITE = 0x1, + + // Section occupies memory during program execution. + SHF_ALLOC = 0x2, + + // Section contains executable machine instructions. + SHF_EXECINSTR = 0x4, + + // The data in this section may be merged. + SHF_MERGE = 0x10, + + // The data in this section is null-terminated strings. + SHF_STRINGS = 0x20, + + // A field in this section holds a section header table index. + SHF_INFO_LINK = 0x40U, + + // Adds special ordering requirements for link editors. + SHF_LINK_ORDER = 0x80U, + + // This section requires special OS-specific processing to avoid incorrect + // behavior. + SHF_OS_NONCONFORMING = 0x100U, + + // This section is a member of a section group. + SHF_GROUP = 0x200U, + + // This section holds Thread-Local Storage. + SHF_TLS = 0x400U, + + // This section is excluded from the final executable or shared library. + SHF_EXCLUDE = 0x80000000U, + + // Start of target-specific flags. + + /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped + /// together by the linker to form the constant pool and the cp register is + /// set to the start of the constant pool by the boot code. + XCORE_SHF_CP_SECTION = 0x800U, + + /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped + /// together by the linker to form the data section and the dp register is + /// set to the start of the section by the boot code. + XCORE_SHF_DP_SECTION = 0x1000U, + + SHF_MASKOS = 0x0ff00000, + + // Bits indicating processor-specific flags. + SHF_MASKPROC = 0xf0000000, + + // If an object file section does not have this flag set, then it may not hold + // more than 2GB and can be freely referred to in objects using smaller code + // models. Otherwise, only objects using larger code models can refer to them. + // For example, a medium code model object can refer to data in a section that + // sets this flag besides being able to refer to data in a section that does + // not set it; likewise, a small code model object can refer only to code in a + // section that does not set this flag. + SHF_X86_64_LARGE = 0x10000000, + + // All sections with the GPREL flag are grouped into a global data area + // for faster accesses + SHF_HEX_GPREL = 0x10000000, + + // Section contains text/data which may be replicated in other sections. + // Linker must retain only one copy. + SHF_MIPS_NODUPES = 0x01000000, + + // Linker must generate implicit hidden weak names. + SHF_MIPS_NAMES = 0x02000000, + + // Section data local to process. + SHF_MIPS_LOCAL = 0x04000000, + + // Do not strip this section. + SHF_MIPS_NOSTRIP = 0x08000000, + + // Section must be part of global data area. + SHF_MIPS_GPREL = 0x10000000, + + // This section should be merged. + SHF_MIPS_MERGE = 0x20000000, + + // Address size to be inferred from section entry size. + SHF_MIPS_ADDR = 0x40000000, + + // Section data is string data by default. + SHF_MIPS_STRING = 0x80000000 + }; + + // Section Group Flags + enum : unsigned { + GRP_COMDAT = 0x1, + GRP_MASKOS = 0x0ff00000, + GRP_MASKPROC = 0xf0000000 + }; + +// 符号信息 +struct Elf32_Sym { + Elf32_Word st_name; // 符号名字,包含了该符号名在字符串表中的下标 + Elf32_Addr st_value; // 符号相对应的值,是一个绝对值,或地址等。不同的符号,含义不同 + Elf32_Word st_size; // 符号的大小 + unsigned char st_info; // 符号的类型和绑定信息 + unsigned char st_other; // 目前为 0,保留 + Elf32_Half st_shndx; // 符号所在段的下标 +}; + +struct Elf64_Sym { + Elf64_Word st_name; // Symbol name (index into string table) + unsigned char st_info; // Symbol's type and binding attributes + unsigned char st_other; // Must be zero; reserved + Elf64_Half st_shndx; // Which section (header tbl index) it's defined in + Elf64_Addr st_value; // Value or address associated with the symbol + Elf64_Xword st_size; // Size of the symbol +}; + +// Relocation entry, without explicit addend. +struct Elf32_Rel { + Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf32_Word r_info; // Symbol table index and type of relocation to apply +}; + +// Relocation entry with explicit addend. +struct Elf32_Rela { + Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf32_Word r_info; // Symbol table index and type of relocation to apply + Elf32_Sword r_addend; // Compute value for relocatable field by adding this +}; + +// Relocation entry, without explicit addend. +struct Elf64_Rel { + Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr). + Elf64_Xword r_info; // Symbol table index and type of relocation to apply. +}; + +// Relocation entry with explicit addend. +struct Elf64_Rela { + Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr). + Elf64_Xword r_info; // Symbol table index and type of relocation to apply. + Elf64_Sxword r_addend; // Compute value for relocatable field by adding this. +}; + +#endif // !ELF_H diff --git a/src/zelf/src/util/Formatter.cpp b/src/zelf/src/util/Formatter.cpp new file mode 100644 index 0000000..aa7c821 --- /dev/null +++ b/src/zelf/src/util/Formatter.cpp @@ -0,0 +1,39 @@ +#include "Formatter.h" +#include +#include +#include + +// TODO: 前面填充 0。 + +char const * Formatter::binary_8_bit(uint8_t n) +{ + char buffer[8 + 1]; + memset(buffer, 0, 8 + 1); +// _itoa_s(n, buffer, 2); + return buffer; +} + +char const* Formatter::binary_16_bit(uint16_t n) +{ + char buffer[16 + 1]; + memset(buffer, 0, 16 + 1); +// itoa_s(n, buffer, 2); + return buffer; +} + +char const* Formatter::binary_32_bit(uint32_t n) +{ + char buffer[32 + 1]; + memset(buffer, 0, 32 + 1); +// _itoa_s(n, buffer, 2); + return buffer; +} + +char const* Formatter::binary_64_bit(uint64_t n) +{ + char buffer[64 + 1]; + memset(buffer, 0, 64 + 1); +// _itoa_s(n, buffer, 2); + return buffer; +} + \ No newline at end of file diff --git a/src/zelf/src/util/Formatter.h b/src/zelf/src/util/Formatter.h new file mode 100644 index 0000000..cc31da9 --- /dev/null +++ b/src/zelf/src/util/Formatter.h @@ -0,0 +1,15 @@ +#ifndef FORMAT_H_ +#define FORMAT_H_ + +#include + +class Formatter +{ +public: + static char const* binary_8_bit(uint8_t n); + static char const* binary_16_bit(uint16_t n); + static char const* binary_32_bit(uint32_t n); + static char const* binary_64_bit(uint64_t n); +}; + +#endif // !FORMAT_H_ diff --git a/src/zelf/src/util/Printer.cpp b/src/zelf/src/util/Printer.cpp new file mode 100644 index 0000000..2dddc1e --- /dev/null +++ b/src/zelf/src/util/Printer.cpp @@ -0,0 +1,43 @@ +#include "Printer.h" +#include "Formatter.h" +#include + +void Printer::print_ushort_hex_array(uint16_t const* array, const unsigned int size) +{ + for (unsigned int i = 0; i < size; i++) + printf("%.4x ", array[i]); + + printf("\n"); +} + +void Printer::print_int_array(int const* array, const unsigned int size) +{ + for (unsigned int i = 0; i < size; i++) + printf("%d ", array[i]); + + printf("\n"); +} + +void Printer::print_hex_array(uint8_t const* array, const unsigned int size) +{ + for (unsigned int i = 0; i < size; i++) + printf("%.2x ", array[i]); + + printf("\n"); +} + +void Printer::print_hex_array2(uint16_t const* array, const unsigned int size) +{ + for (unsigned int i = 0; i < size; i++) + printf("%.4x ", array[i]); + + printf("\n"); +} + +void Printer::print_char_array(unsigned char const* array, const unsigned int size) +{ + for (unsigned int i = 0; i < size; i++) + printf("%.2x ", array[i]); + + printf("\n"); +} diff --git a/src/zelf/src/util/Printer.h b/src/zelf/src/util/Printer.h new file mode 100644 index 0000000..38b2a2b --- /dev/null +++ b/src/zelf/src/util/Printer.h @@ -0,0 +1,15 @@ +#ifndef PRINTER_H +#define PRINTER_H +#include + +class Printer +{ +public: + static void print_ushort_hex_array(uint16_t const* array, const unsigned int size); + static void print_int_array(int const* array, const unsigned int size); + static void print_hex_array(uint8_t const* array, const unsigned int size); + static void print_hex_array2(uint16_t const* array, const unsigned int size); + static void print_char_array(unsigned char const* array, const unsigned int size); +}; + +#endif // !PRINTER_H \ No newline at end of file diff --git a/src/zelf/xmake.lua b/src/zelf/xmake.lua new file mode 100644 index 0000000..aee658e --- /dev/null +++ b/src/zelf/xmake.lua @@ -0,0 +1,5 @@ +target("zelf") + set_rundir(".") + set_kind("binary") + add_files("src/*.cpp","src/**/*.cpp") + add_headerfiles("src/*.h","src/**/*.h") diff --git a/src/zfile/.gitignore b/src/zfile/.gitignore new file mode 100644 index 0000000..1521057 --- /dev/null +++ b/src/zfile/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + + diff --git a/src/zfile/src/main.cpp b/src/zfile/src/main.cpp new file mode 100644 index 0000000..7c435d2 --- /dev/null +++ b/src/zfile/src/main.cpp @@ -0,0 +1,9 @@ +#include + +using namespace std; + +int main(int argc, char** argv) +{ + cout << "hello world!" << endl; + return 0; +} diff --git a/src/zfile/src/parse.cpp b/src/zfile/src/parse.cpp new file mode 100644 index 0000000..e739fa3 --- /dev/null +++ b/src/zfile/src/parse.cpp @@ -0,0 +1,9 @@ +#include "parse.h" +#include + +void FilePackage::Serialize(FArchive& Ar) +{ + FileHeader st; + Ar.Serialize(&st, sizeof(FileHeader)); + +} diff --git a/src/zfile/src/parse.h b/src/zfile/src/parse.h new file mode 100644 index 0000000..803d340 --- /dev/null +++ b/src/zfile/src/parse.h @@ -0,0 +1,66 @@ +#include + +#define UINT16 unsigned int +#define UINT32 unsigned int +#define BYTES unsigned char* +#define byte unsigned char +#define appError +class FArchive { +protected: + int ArPos; + int ArStarter; + int ArStopper; + int DataSize; + const byte* DataPtr; +private: + +public: + virtual void Seek(int Pos) + { + Pos += ArStarter; + assert(Pos >= 0 && Pos <= DataSize); + ArPos = Pos; + } + virtual void Serialize(void* data, int size) + { + if (ArStopper > 0 && ArPos + size > ArStopper) + appError("Serializing behind stopper (%X+%X > %X)", ArPos, size, ArStopper); + else if (ArPos + size > DataSize) + appError("Serializing behind end of buffer"); + memcpy(data, DataPtr + ArPos, size); + ArPos += size; + } +public: + virtual bool IsEof() const + { + return ArPos >= DataSize; + } +}; +typedef struct { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} FileHeader; +typedef struct { + char Name[8]; //8 bytes long null-terminated string + UINT32 VirtualSize; //total size of section when loaded into memory, 0 for COFF, might be different because of padding + UINT32 VirtualAddress; //address of the first byte of the section before relocations are applied, should be set to 0 + UINT32 SizeOfRawData; //The size of the section for COFF files + UINT32 PointerToRawData; //Pointer to the beginning of the section for COFF + UINT32 PointerToRelocations; //File pointer to the beginning of relocation entries + UINT32 PointerToLinenumbers; //The file pointer to the beginning of line-number entries for the section. T + UINT16 NumberOfRelocations; //The number of relocation entries for the section. This is set to zero for executable images. + UINT16 NumberOfLinenumbers; //The number of line-number entries for the section. This value should be zero for an image because COFF debugging information is deprecated. + UINT32 Characteristics; //The flags that describe the characteristics of the section +} SectionHeader; +class FilePackage { + +public: + virtual void Serialize(FArchive& Ar); +private: + +}; \ No newline at end of file diff --git a/thridpart/log.txt b/thridpart/log.txt new file mode 100644 index 0000000..508a3b3 --- /dev/null +++ b/thridpart/log.txt @@ -0,0 +1,459 @@ +PS D:\zlua> xmake project -k vsxmake2022 -m "debug;release" +scope. table: 00000291F094EEB0 table: 00000291F094E330 nil theme C:\Program Files\xmake\themes\default nil nil +scope. table: 00000291F094CFB0 table: 00000291F094CAF0 nil theme C:\Program Files\xmake\themes\default nil nil +scope. table: 00000291F0BBC0D0 table: 00000291F0BBB010 nil task C:\Program Files\xmake\plugins\check plugin nil +scope. table: 00000291F0BBE110 table: 00000291F0BBD890 nil task C:\Program Files\xmake\plugins\doxygen plugin nil +scope. table: 00000291F0B5FA20 table: 00000291F0B5D720 nil task C:\Program Files\xmake\plugins\format plugin nil +scope. table: 00000291F0B629A0 table: 00000291F0B60BE0 nil task C:\Program Files\xmake\plugins\lua plugin nil +scope. table: 00000291F0950D30 table: 00000291F094D870 nil task C:\Program Files\xmake\plugins\macro plugin nil +scope. table: 00000291F0B12E30 table: 00000291F0953830 nil task C:\Program Files\xmake\plugins\plugin plugin nil +scope. table: 00000291F0BDF760 table: 00000291F0B14170 nil task C:\Program Files\xmake\plugins\project plugin nil +scope. table: 00000291F0BE2E60 table: 00000291F0BE0FA0 nil task C:\Program Files\xmake\plugins\repo plugin nil +scope. table: 00000291F0BE5A60 table: 00000291F0BE3760 nil task C:\Program Files\xmake\plugins\show plugin nil +scope. table: 00000291F0BE9C60 table: 00000291F0BE6220 nil task C:\Program Files\xmake\plugins\watch plugin nil +scope. table: 00000291F0BEED20 table: 00000291F0BEB1E0 nil task C:\Program Files\xmake\actions\build main nil +scope. table: 00000291F0C01910 table: 00000291F0C00650 nil task C:\Program Files\xmake\actions\clean action nil +scope. table: 00000291F0C05D10 table: 00000291F0C03FD0 nil task C:\Program Files\xmake\actions\config action nil +scope. table: 00000291F0C09CD0 table: 00000291F0C07F10 nil task C:\Program Files\xmake\actions\create action nil +scope. table: 00000291F0C0CC50 table: 00000291F0C0B6D0 nil task C:\Program Files\xmake\actions\global action nil +scope. table: 00000291F0C3C960 table: 00000291F0C0E950 nil task C:\Program Files\xmake\actions\install action nil +scope. table: 00000291F0C3F860 table: 00000291F0C3DAE0 nil task C:\Program Files\xmake\actions\package action nil +scope. table: 00000291F0C438A0 table: 00000291F0C40960 nil task C:\Program Files\xmake\actions\require action nil +scope. table: 00000291F0C464E0 table: 00000291F0C44CE0 nil task C:\Program Files\xmake\actions\run action nil +scope. table: 00000291F0C48DE0 table: 00000291F0C48BA0 nil task C:\Program Files\xmake\actions\service action nil +scope. table: 00000291F0C3B1E0 table: 00000291F0C4ABA0 nil task C:\Program Files\xmake\actions\uninstall action nil +scope. table: 00000291F1145990 table: 00000291F1145450 nil task C:\Program Files\xmake\actions\update action nil +scope. table: 00000291F1160750 table: 00000291F1160D90 nil language C:\Program Files\xmake\languages\asm nil nil +scope. table: 00000291F1163510 table: 00000291F11634D0 nil language C:\Program Files\xmake\languages\c++ nil nil +scope. table: 00000291F118B8A0 table: 00000291F118B3E0 nil language C:\Program Files\xmake\languages\cuda nil nil +scope. table: 00000291F118C9A0 table: 00000291F118D420 nil language C:\Program Files\xmake\languages\dlang nil nil +scope. table: 00000291F1190720 table: 00000291F118FE20 nil language C:\Program Files\xmake\languages\fortrannil nil +scope. table: 00000291F11926E0 table: 00000291F11927E0 nil language C:\Program Files\xmake\languages\golang +nil nil +scope. table: 00000291F1192A20 table: 00000291F11935A0 nil language C:\Program Files\xmake\languages\msrc nil nil +scope. table: 00000291F1194E20 table: 00000291F1195320 nil language C:\Program Files\xmake\languages\nim nil nil +scope. table: 00000291F11985E0 table: 00000291F1197960 nil language C:\Program Files\xmake\languages\objc++ +nil nil +scope. table: 00000291F1199CE0 table: 00000291F119A060 nil language C:\Program Files\xmake\languages\pascal +nil nil +scope. table: 00000291F119BAA0 table: 00000291F119C220 nil language C:\Program Files\xmake\languages\rust nil nil +scope. table: 00000291F118E8A0 table: 00000291F118D660 nil language C:\Program Files\xmake\languages\swift nil nil +scope. table: 00000291F1191B20 table: 00000291F1191FA0 nil language C:\Program Files\xmake\languages\zig nil nil +scope. table: 00000291F0BE07A0 table: 00000291F0BDF420 nil root nil nil zlua +scope. table: 00000291F0BE0860 table: 00000291F0BE09A0 nil root.target nil nil nil +scope. table: 00000291F1412820 table: 00000291F14132A0 nil platform C:\Program Files\xmake\platforms\androidnil nil +scope. table: 00000291F1414820 table: 00000291F14147E0 nil platform C:\Program Files\xmake\platforms\appletvos nil nil +scope. table: 00000291F1417DE0 table: 00000291F1418060 nil platform C:\Program Files\xmake\platforms\bsd nil nil +scope. table: 00000291F141A220 table: 00000291F141A060 nil platform C:\Program Files\xmake\platforms\cross nil nil +scope. table: 00000291F141B5E0 table: 00000291F141BB20 nil platform C:\Program Files\xmake\platforms\cygwin +nil nil +scope. table: 00000291F141DCE0 table: 00000291F141DA20 nil platform C:\Program Files\xmake\platforms\haiku nil nil +scope. table: 00000291F141F560 table: 00000291F1420060 nil platform C:\Program Files\xmake\platforms\iphoneos nil nil +scope. table: 00000291F1422F20 table: 00000291F14226E0 nil platform C:\Program Files\xmake\platforms\linux nil nil +scope. table: 00000291F1425820 table: 00000291F1425520 nil platform C:\Program Files\xmake\platforms\macosx +nil nil +scope. table: 00000291F14282E0 table: 00000291F14279A0 nil platform C:\Program Files\xmake\platforms\mingw nil nil +scope. table: 00000291F142A2A0 table: 00000291F142A1E0 nil platform C:\Program Files\xmake\platforms\msys nil nil +scope. table: 00000291F142BAA0 table: 00000291F142C160 nil platform C:\Program Files\xmake\platforms\wasm nil nil +scope. table: 00000291F140CCE0 table: 00000291F140C560 nil platform C:\Program Files\xmake\platforms\watchosnil nil +scope. table: 00000291F148F710 table: 00000291F148F410 nil platform C:\Program Files\xmake\platforms\windowsnil nil +scope. table: 00000291F1496A50 table: 00000291F1496690 nil root nil nil zlua +scope. table: 00000291F1496510 table: 00000291F1496D50 nil root.target nil nil nil +scope. table: 00000291F14996D0 table: 00000291F1499510 nil toolchain C:\Program Files\xmake\toolchains\msvc nil nil +scope. table: 00000291F149D190 table: 00000291F149C990 nil toolchain C:\Program Files\xmake\toolchains\clang +nil nil +scope. table: 00000291F149E610 table: 00000291F149EAD0 nil toolchain C:\Program Files\xmake\toolchains\yasm nil nil +scope. table: 00000291F14A0310 table: 00000291F14A02D0 nil toolchain C:\Program Files\xmake\toolchains\nasm nil nil +scope. table: 00000291F14A3750 table: 00000291F14A3AD0 nil toolchain C:\Program Files\xmake\toolchains\cuda nil nil +scope. table: 00000291F14A6490 table: 00000291F14A6450 nil toolchain C:\Program Files\xmake\toolchains\rust nil nil +scope. table: 00000291F14A92D0 table: 00000291F14A9410 nil toolchain C:\Program Files\xmake\toolchains\swift +nil nil +scope. table: 00000291F148C250 table: 00000291F148C850 nil toolchain C:\Program Files\xmake\toolchains\go nil nil +scope. table: 00000291F130BF60 table: 00000291F130BE20 nil toolchain C:\Program Files\xmake\toolchains\gfortran nil nil +scope. table: 00000291F130D4A0 table: 00000291F130D8A0 nil toolchain C:\Program Files\xmake\toolchains\zig nil nil +scope. table: 00000291F13122E0 table: 00000291F1311C60 nil toolchain C:\Program Files\xmake\toolchains\fpc nil nil +scope. table: 00000291F1315220 table: 00000291F1315320 nil toolchain C:\Program Files\xmake\toolchains\nim nil nil +scope. table: 00000291F1316620 table: 00000291F1315DE0 nil toolchain C:\Program Files\xmake\toolchains\msvc nil nil +checking for Microsoft Visual Studio (x64) version ... 2022 +scope. table: 00000291F1428F20 table: 00000291F1428D20 nil toolchain C:\Program Files\xmake\toolchains\clang +nil nil +scope. table: 00000291F142A220 table: 00000291F1429260 nil toolchain C:\Program Files\xmake\toolchains\yasm nil nil +scope. table: 00000291F142A320 table: 00000291F14299E0 nil toolchain C:\Program Files\xmake\toolchains\nasm nil nil +scope. table: 00000291F142A360 table: 00000291F142A160 nil toolchain C:\Program Files\xmake\toolchains\cuda nil nil +scope. table: 00000291F1429A20 table: 00000291F14297A0 nil toolchain C:\Program Files\xmake\toolchains\rust nil nil +scope. table: 00000291F1429E20 table: 00000291F1429D20 nil toolchain C:\Program Files\xmake\toolchains\swift +nil nil +scope. table: 00000291F142A9E0 table: 00000291F142A560 nil toolchain C:\Program Files\xmake\toolchains\go nil nil +scope. table: 00000291F142AC20 table: 00000291F142A7A0 nil toolchain C:\Program Files\xmake\toolchains\gfortran nil nil +scope. table: 00000291F142A9A0 table: 00000291F142B3A0 nil toolchain C:\Program Files\xmake\toolchains\zig nil nil +scope. table: 00000291F115C210 table: 00000291F115B790 nil toolchain C:\Program Files\xmake\toolchains\fpc nil nil +scope. table: 00000291F115BA50 table: 00000291F115C490 nil toolchain C:\Program Files\xmake\toolchains\nim nil nil +scope. table: 00000291F1153210 table: 00000291F114D910 nil root nil nil zlua +scope. table: 00000291F1155810 table: 00000291F1153490 nil root.target nil nil nil +scope. table: 00000291F11A8CA0 table: 00000291F11A6460 nil root nil nil zlua +scope. table: 00000291F118C5E0 table: 00000291F11AA5E0 nil root.target nil nil nil +scope. table: 00000291F0C48920 table: 00000291F0C48460 nil package D:\zlua\thridpart\luasocket nil nil +scope. table: 00000291F0C48020 table: 00000291F0C48520 nil package D:\zlua\thridpart\lua-protobuf nil nil +scope. table: 00000291F16481C0 table: 00000291F1648240 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\l\lua nil nil +scope. table: 00000291F1656040 table: 00000291F16559C0 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\p\protobuf-cpp nil nil +scope. table: 00000291F165FB40 table: 00000291F165F5C0 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\c\cmake nil nil +scope. table: 00000291F1814F40 table: 00000291F18139C0 nil root nil nil zlua +scope. table: 00000291F1816AC0 table: 00000291F18158C0 nil root.target nil nil nil +scope. table: 00000291F181CC40 table: 00000291F1817440 nil target D:\zlua\src\clua nil nil +scope. table: 00000291F16DE0C0 table: 00000291F16DBD80 nil rule C:\Program Files\xmake\rules\asm nil nil +scope. table: 00000291F16DE740 table: 00000291F16DDD40 nil rule C:\Program Files\xmake\rules\asm nil nil +scope. table: 00000291F16DF680 table: 00000291F16DF580 nil rule C:\Program Files\xmake\rules\asn1c nil nil +scope. table: 00000291F16E07C0 table: 00000291F16E0800 nil rule C:\Program Files\xmake\rules\c++\build_optimization nil nil +scope. table: 00000291F16E1580 table: 00000291F16E1FC0 nil rule C:\Program Files\xmake\rules\c++\build_optimization nil nil +scope. table: 00000291F16E8080 table: 00000291F16E53C0 nil rule C:\Program Files\xmake\rules\c++\modules nil nil +scope. table: 00000291F16EA040 table: 00000291F16E8280 nil rule C:\Program Files\xmake\rules\c++\modules nil nil +scope. table: 00000291F16EA440 table: 00000291F16E9540 nil rule C:\Program Files\xmake\rules\c++\modules nil nil +scope. table: 00000291F16EC100 table: 00000291F16EBF80 nil rule C:\Program Files\xmake\rules\c++\openmp nil nil +scope. table: 00000291F16EC900 table: 00000291F16EB480 nil rule C:\Program Files\xmake\rules\c++\openmp nil nil +scope. table: 00000291F16EE200 table: 00000291F16EDFC0 nil rule C:\Program Files\xmake\rules\c++\precompiled_header nil nil +scope. table: 00000291F16ED980 table: 00000291F16ED680 nil rule C:\Program Files\xmake\rules\c++\precompiled_header nil nil +scope. table: 00000291F16F0240 table: 00000291F16EF340 nil rule C:\Program Files\xmake\rules\c++\unity_build nil nil +scope. table: 00000291F16EFA00 table: 00000291F16EF4C0 nil rule C:\Program Files\xmake\rules\c++\unity_build nil nil +scope. table: 00000291F16D50C0 table: 00000291F16F3740 nil rule C:\Program Files\xmake\rules\c++ nil nil +scope. table: 00000291F1649840 table: 00000291F16D4480 nil rule C:\Program Files\xmake\rules\c++ nil nil +scope. table: 00000291F164AD80 table: 00000291F1649A40 nil rule C:\Program Files\xmake\rules\c++ nil nil +scope. table: 00000291F164CEC0 table: 00000291F164D0C0 nil rule C:\Program Files\xmake\rules\c51 nil nil +scope. table: 00000291F164D3C0 table: 00000291F164DC80 nil rule C:\Program Files\xmake\rules\capnproto nil nil +scope. table: 00000291F1650040 table: 00000291F164E700 nil rule C:\Program Files\xmake\rules\cuda\devlink nil nil +scope. table: 00000291F1650F00 table: 00000291F1650CC0 nil rule C:\Program Files\xmake\rules\cuda\env nil nil +scope. table: 00000291F1651800 table: 00000291F1651EC0 nil rule C:\Program Files\xmake\rules\cuda\gencodes nil nil +scope. table: 00000291F1655640 table: 00000291F1654340 nil rule C:\Program Files\xmake\rules\cuda nil nil +scope. table: 00000291F1657780 table: 00000291F1655900 nil rule C:\Program Files\xmake\rules\cuda nil nil +scope. table: 00000291F1658340 table: 00000291F16572C0 nil rule C:\Program Files\xmake\rules\dlang\build_optimization nil nil +scope. table: 00000291F165C740 table: 00000291F165AB00 nil rule C:\Program Files\xmake\rules\dlang nil nil +scope. table: 00000291F165F480 table: 00000291F165CAC0 nil rule C:\Program Files\xmake\rules\dlang nil nil +scope. table: 00000291F1662700 table: 00000291F1661940 nil rule C:\Program Files\xmake\rules\fortran nil nil +scope. table: 00000291F16646C0 table: 00000291F1662900 nil rule C:\Program Files\xmake\rules\fortran nil nil +scope. table: 00000291F1664480 table: 00000291F1664DC0 nil rule C:\Program Files\xmake\rules\fortran nil nil +scope. table: 00000291F155C460 table: 00000291F155CBA0 nil rule C:\Program Files\xmake\rules\gnu-rm nil nil +scope. table: 00000291F155DB20 table: 00000291F155DCA0 nil rule C:\Program Files\xmake\rules\gnu-rm nil nil +scope. table: 00000291F155D320 table: 00000291F155E020 nil rule C:\Program Files\xmake\rules\gnu-rm nil nil +scope. table: 00000291F155EC60 table: 00000291F155DFE0 nil rule C:\Program Files\xmake\rules\gnu-rm nil nil +scope. table: 00000291F155F3A0 table: 00000291F155F660 nil rule C:\Program Files\xmake\rules\go\env nil nil +scope. table: 00000291F15654A0 table: 00000291F1564720 nil rule C:\Program Files\xmake\rules\go nil nil +scope. table: 00000291F1566260 table: 00000291F15657E0 nil rule C:\Program Files\xmake\rules\go nil nil +scope. table: 00000291F15694E0 table: 00000291F15687A0 nil rule C:\Program Files\xmake\rules\iverilog nil nil +scope. table: 00000291F156E420 table: 00000291F156BDA0 nil rule C:\Program Files\xmake\rules\lex_yacc\lex nil nil +scope. table: 00000291F1572EE0 table: 00000291F1570C60 nil rule C:\Program Files\xmake\rules\lex_yacc\yacc nil nil +scope. table: 00000291F1556AA0 table: 00000291F15536E0 nil rule C:\Program Files\xmake\rules\linker\link_scriptsnil nil +scope. table: 00000291F155AD20 table: 00000291F15586E0 nil rule C:\Program Files\xmake\rules\linker\version_scripts nil nil +scope. table: 00000291F1490F90 table: 00000291F155BCE0 nil rule C:\Program Files\xmake\rules\linker nil nil +scope. table: 00000291F14918D0 table: 00000291F14911D0 nil rule C:\Program Files\xmake\rules\luarocks\module nil nil +scope. table: 00000291F1493E90 table: 00000291F1493B90 nil rule C:\Program Files\xmake\rules\mdk nil nil +scope. table: 00000291F1494E10 table: 00000291F1493C90 nil rule C:\Program Files\xmake\rules\mdk nil nil +scope. table: 00000291F1494F90 table: 00000291F1494990 nil rule C:\Program Files\xmake\rules\mdk nil nil +scope. table: 00000291F149B2D0 table: 00000291F149BED0 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149C5D0 table: 00000291F149B750 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149C2D0 table: 00000291F149C510 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149CF50 table: 00000291F149CCD0 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149DB90 table: 00000291F149CC10 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149D090 table: 00000291F149D210 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149D2D0 table: 00000291F149DED0 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149D590 table: 00000291F149DA10 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149E8D0 table: 00000291F149E210 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149EA10 table: 00000291F149EF10 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149FC50 table: 00000291F149EF50 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149F3D0 table: 00000291F149FF90 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F149F490 table: 00000291F149FED0 nil rule C:\Program Files\xmake\rules\mode nil nil +scope. table: 00000291F14A3250 table: 00000291F14A1590 nil rule C:\Program Files\xmake\rules\nim nil nil +scope. table: 00000291F14A59D0 table: 00000291F14A3C90 nil rule C:\Program Files\xmake\rules\nim nil nil +scope. table: 00000291F1308E60 table: 00000291F14AB990 nil rule C:\Program Files\xmake\rules\objc++ nil nil +scope. table: 00000291F130D360 table: 00000291F1308DE0 nil rule C:\Program Files\xmake\rules\objc++ nil nil +scope. table: 00000291F1311420 table: 00000291F130D660 nil rule C:\Program Files\xmake\rules\objc++ nil nil +scope. table: 00000291F1316C60 table: 00000291F13153E0 nil rule C:\Program Files\xmake\rules\pascal nil nil +scope. table: 00000291F1317920 table: 00000291F13165A0 nil rule C:\Program Files\xmake\rules\pascal nil nil +scope. table: 00000291F131C220 table: 00000291F131BD60 nil rule C:\Program Files\xmake\rules\platform\linux\bpf +nil nil +scope. table: 00000291F131F460 table: 00000291F131ED60 nil rule C:\Program Files\xmake\rules\platform\linux\driver nil nil +scope. table: 00000291F1321560 table: 00000291F1320AA0 nil rule C:\Program Files\xmake\rules\platform\wasm\installfiles nil nil +scope. table: 00000291F1322B60 table: 00000291F13230E0 nil rule C:\Program Files\xmake\rules\platform\wasm\preloadfiles nil nil +scope. table: 00000291F13251E0 table: 00000291F13242A0 nil rule C:\Program Files\xmake\rules\platform\windows\def nil nil +scope. table: 00000291F13268E0 table: 00000291F1326560 nil rule C:\Program Files\xmake\rules\platform\windows\manifest nil nil +scope. table: 00000291F140D860 table: 00000291F140DAE0 nil rule C:\Program Files\xmake\rules\platform nil nil +scope. table: 00000291F140FE20 table: 00000291F140EBE0 nil rule C:\Program Files\xmake\rules\platform nil nil +scope. table: 00000291F14130E0 table: 00000291F1411CA0 nil rule C:\Program Files\xmake\rules\plugin\compile_commands nil nil +scope. table: 00000291F14146E0 table: 00000291F14135A0 nil rule C:\Program Files\xmake\rules\plugin\vsxmake nil nil +scope. table: 00000291F141AF20 table: 00000291F141A320 nil rule C:\Program Files\xmake\rules\protobuf nil nil +scope. table: 00000291F141B960 table: 00000291F141A7A0 nil rule C:\Program Files\xmake\rules\protobuf nil nil +scope. table: 00000291F141DB60 table: 00000291F141E460 nil rule C:\Program Files\xmake\rules\python nil nil +scope. table: 00000291F141F760 table: 00000291F141FBA0 nil rule C:\Program Files\xmake\rules\qt\env nil nil +scope. table: 00000291F1428120 table: 00000291F1423860 nil rule C:\Program Files\xmake\rules\qt\moc nil nil +scope. table: 00000291F11595D0 table: 00000291F142B6A0 nil rule C:\Program Files\xmake\rules\qt\qmltyperegistrarnil nil +scope. table: 00000291F115DB10 table: 00000291F115C410 nil rule C:\Program Files\xmake\rules\qt\qrc nil nil +scope. table: 00000291F1162BD0 table: 00000291F1160A50 nil rule C:\Program Files\xmake\rules\qt\ui nil nil +scope. table: 00000291F0C088D0 table: 00000291F1191BA0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0BFFF90 table: 00000291F0C09F50 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0C47620 table: 00000291F0C3EBE0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0C4AB60 table: 00000291F0C478A0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0C3CA20 table: 00000291F0C49DE0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0BEA6E0 table: 00000291F0C3C3E0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0BED820 table: 00000291F0BEBF60 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0BB1ED0 table: 00000291F0BED1A0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0BB8B50 table: 00000291F0BB28D0 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0B61D60 table: 00000291F0BB8050 nil rule C:\Program Files\xmake\rules\qt nil nil +scope. table: 00000291F0B136F0 table: 00000291F0952870 nil rule C:\Program Files\xmake\rules\rust nil nil +scope. table: 00000291F1959580 table: 00000291F0B149F0 nil rule C:\Program Files\xmake\rules\rust nil nil +scope. table: 00000291F1959100 table: 00000291F1958EC0 nil rule C:\Program Files\xmake\rules\rust nil nil +scope. table: 00000291F195B400 table: 00000291F195BB00 nil rule C:\Program Files\xmake\rules\swift nil nil +scope. table: 00000291F195C8C0 table: 00000291F195B100 nil rule C:\Program Files\xmake\rules\swift nil nil +scope. table: 00000291F195FB80 table: 00000291F195E680 nil rule C:\Program Files\xmake\rules\swig nil nil +scope. table: 00000291F195ED00 table: 00000291F195F880 nil rule C:\Program Files\xmake\rules\swig nil nil +scope. table: 00000291F1960A40 table: 00000291F195EBC0 nil rule C:\Program Files\xmake\rules\swig nil nil +scope. table: 00000291F1962440 table: 00000291F1960C80 nil rule C:\Program Files\xmake\rules\utils\bin2c nil nil +scope. table: 00000291F1963840 table: 00000291F1962500 nil rule C:\Program Files\xmake\rules\utils\compiler_runtime nil nil +scope. table: 00000291F1968A40 table: 00000291F1963C40 nil rule C:\Program Files\xmake\rules\utils\glsl2spv nil nil +scope. table: 00000291F1968F00 table: 00000291F1969940 nil rule C:\Program Files\xmake\rules\utils\inherit_linksnil nil +scope. table: 00000291F196A080 table: 00000291F196A580 nil rule C:\Program Files\xmake\rules\utils\install_importfiles nil nil +scope. table: 00000291F196B6C0 table: 00000291F196A600 nil rule C:\Program Files\xmake\rules\utils\install_importfiles nil nil +scope. table: 00000291F196C780 table: 00000291F196C140 nil rule C:\Program Files\xmake\rules\utils\ispc nil nil +scope. table: 00000291F196EA40 table: 00000291F196D280 nil rule C:\Program Files\xmake\rules\utils\merge_archivenil nil +scope. table: 00000291F1970A00 table: 00000291F196ED40 nil rule C:\Program Files\xmake\rules\utils\merge_object +nil nil +scope. table: 00000291F1970CC0 table: 00000291F1971580 nil rule C:\Program Files\xmake\rules\utils\symbols\export_all nil nil +scope. table: 00000291F1972600 table: 00000291F1972880 nil rule C:\Program Files\xmake\rules\utils\symbols\export_list nil nil +scope. table: 00000291F19730C0 table: 00000291F1972FC0 nil rule C:\Program Files\xmake\rules\utils\symbols\extract nil nil +scope. table: 00000291F1976EC0 table: 00000291F1976680 nil rule C:\Program Files\xmake\rules\vala nil nil +scope. table: 00000291F1957D00 table: 00000291F1977300 nil rule C:\Program Files\xmake\rules\vala nil nil +scope. table: 00000291F19AD3C0 table: 00000291F19AD740 nil rule C:\Program Files\xmake\rules\verilator nil nil +scope. table: 00000291F19B1000 table: 00000291F19AF7C0 nil rule C:\Program Files\xmake\rules\wdk\env nil nil +scope. table: 00000291F19B1040 table: 00000291F19B0D00 nil rule C:\Program Files\xmake\rules\wdk\env nil nil +scope. table: 00000291F19B11C0 table: 00000291F19B0940 nil rule C:\Program Files\xmake\rules\wdk\env nil nil +scope. table: 00000291F19B1400 table: 00000291F19B1B80 nil rule C:\Program Files\xmake\rules\wdk\env nil nil +scope. table: 00000291F19B3AC0 table: 00000291F19B2580 nil rule C:\Program Files\xmake\rules\wdk\inf nil nil +scope. table: 00000291F19B5EC0 table: 00000291F19B52C0 nil rule C:\Program Files\xmake\rules\wdk\man nil nil +scope. table: 00000291F19B7B80 table: 00000291F19B6F40 nil rule C:\Program Files\xmake\rules\wdk\mc nil nil +scope. table: 00000291F19B9180 table: 00000291F19B8680 nil rule C:\Program Files\xmake\rules\wdk\mof nil nil +scope. table: 00000291F19BAAC0 table: 00000291F19BAF40 nil rule C:\Program Files\xmake\rules\wdk\package nil nil +scope. table: 00000291F19BCA00 table: 00000291F19BC540 nil rule C:\Program Files\xmake\rules\wdk\sign nil nil +scope. table: 00000291F19BE300 table: 00000291F19BD600 nil rule C:\Program Files\xmake\rules\wdk\tracewpp nil nil +scope. table: 00000291F19C2200 table: 00000291F19C1DC0 nil rule C:\Program Files\xmake\rules\wdk nil nil +scope. table: 00000291F19C4FC0 table: 00000291F19C3040 nil rule C:\Program Files\xmake\rules\wdk nil nil +scope. table: 00000291F19C5C00 table: 00000291F19C4A80 nil rule C:\Program Files\xmake\rules\wdk nil nil +scope. table: 00000291F19C7F40 table: 00000291F19C5840 nil rule C:\Program Files\xmake\rules\wdk nil nil +scope. table: 00000291F19C8E00 table: 00000291F19C8A40 nil rule C:\Program Files\xmake\rules\winsdk\dotnet nil nil +scope. table: 00000291F19C9B80 table: 00000291F19C9A40 nil rule C:\Program Files\xmake\rules\winsdk\mfc\env nil nil +scope. table: 00000291F19ABD80 table: 00000291F19CBA80 nil rule C:\Program Files\xmake\rules\winsdk\mfc nil nil +scope. table: 00000291F19AC080 table: 00000291F19ABDC0 nil rule C:\Program Files\xmake\rules\winsdk\mfc nil nil +scope. table: 00000291F19DFEB0 table: 00000291F19ABA40 nil rule C:\Program Files\xmake\rules\winsdk\mfc nil nil +scope. table: 00000291F19DF4B0 table: 00000291F19DFF30 nil rule C:\Program Files\xmake\rules\winsdk\mfc nil nil +scope. table: 00000291F19E1CB0 table: 00000291F19E11B0 nil rule C:\Program Files\xmake\rules\winsdk nil nil +scope. table: 00000291F19E2EB0 table: 00000291F19E1230 nil rule C:\Program Files\xmake\rules\winsdk nil nil +scope. table: 00000291F19E7930 table: 00000291F19E4CB0 nil rule C:\Program Files\xmake\rules\xcode\application nil nil +scope. table: 00000291F19EA1B0 table: 00000291F19E9A70 nil rule C:\Program Files\xmake\rules\xcode\bundle nil nil +scope. table: 00000291F19EC9F0 table: 00000291F19ED0F0 nil rule C:\Program Files\xmake\rules\xcode\framework nil nil +scope. table: 00000291F19EE170 table: 00000291F19ED7F0 nil rule C:\Program Files\xmake\rules\xcode\info_plist nil nil +scope. table: 00000291F19F0030 table: 00000291F19EF8F0 nil rule C:\Program Files\xmake\rules\xcode\metal nil nil +scope. table: 00000291F19F09F0 table: 00000291F19F0370 nil rule C:\Program Files\xmake\rules\xcode\storyboard nil nil +scope. table: 00000291F19F2AB0 table: 00000291F19F17B0 nil rule C:\Program Files\xmake\rules\xcode\xcassets nil nil +scope. table: 00000291F19F4070 table: 00000291F19F3370 nil rule C:\Program Files\xmake\rules\xmake_cli nil nil +scope. table: 00000291F19F5830 table: 00000291F19F5C30 nil rule C:\Program Files\xmake\rules\zig nil nil +scope. table: 00000291F19F8130 table: 00000291F19F5A30 nil rule C:\Program Files\xmake\rules\zig nil nil +checking for debug.x64 ... +scope. table: 00000291F1605D00 table: 00000291F1605480 nil toolchain C:\Program Files\xmake\toolchains\msvc nil nil +scope. table: 00000291F1607FC0 table: 00000291F1608340 nil toolchain C:\Program Files\xmake\toolchains\clang +nil nil +scope. table: 00000291F1609E40 table: 00000291F1609A80 nil toolchain C:\Program Files\xmake\toolchains\yasm nil nil +scope. table: 00000291F160AD00 table: 00000291F160A780 nil toolchain C:\Program Files\xmake\toolchains\nasm nil nil +scope. table: 00000291F160D0C0 table: 00000291F160DC80 nil toolchain C:\Program Files\xmake\toolchains\cuda nil nil +scope. table: 00000291F160F080 table: 00000291F160FD00 nil toolchain C:\Program Files\xmake\toolchains\rust nil nil +scope. table: 00000291F1611340 table: 00000291F1610FC0 nil toolchain C:\Program Files\xmake\toolchains\swift +nil nil +scope. table: 00000291F1613500 table: 00000291F1613F40 nil toolchain C:\Program Files\xmake\toolchains\go nil nil +scope. table: 00000291F1615940 table: 00000291F1614300 nil toolchain C:\Program Files\xmake\toolchains\gfortran nil nil +scope. table: 00000291F1616540 table: 00000291F1616C80 nil toolchain C:\Program Files\xmake\toolchains\zig nil nil +scope. table: 00000291F16180C0 table: 00000291F1617FC0 nil toolchain C:\Program Files\xmake\toolchains\fpc nil nil +scope. table: 00000291F161A940 table: 00000291F16194C0 nil toolchain C:\Program Files\xmake\toolchains\nim nil nil +scope. table: 00000291F161A280 table: 00000291F161A340 nil toolchain C:\Program Files\xmake\toolchains\msvc nil nil +checking for Microsoft Visual Studio (x64) version ... 2022 +scope. table: 00000291F1617600 table: 00000291F1617F40 nil toolchain C:\Program Files\xmake\toolchains\clang +nil nil +scope. table: 00000291F16170C0 table: 00000291F16174C0 nil toolchain C:\Program Files\xmake\toolchains\yasm nil nil +scope. table: 00000291F1617140 table: 00000291F1617AC0 nil toolchain C:\Program Files\xmake\toolchains\nasm nil nil +scope. table: 00000291F16172C0 table: 00000291F16171C0 nil toolchain C:\Program Files\xmake\toolchains\cuda nil nil +scope. table: 00000291F1617500 table: 00000291F16173C0 nil toolchain C:\Program Files\xmake\toolchains\rust nil nil +scope. table: 00000291F1618CC0 table: 00000291F1618080 nil toolchain C:\Program Files\xmake\toolchains\swift +nil nil +scope. table: 00000291F1618400 table: 00000291F1618EC0 nil toolchain C:\Program Files\xmake\toolchains\go nil nil +scope. table: 00000291F1618340 table: 00000291F1618240 nil toolchain C:\Program Files\xmake\toolchains\gfortran nil nil +scope. table: 00000291F1618B80 table: 00000291F1618B00 nil toolchain C:\Program Files\xmake\toolchains\zig nil nil +scope. table: 00000291F161BA00 table: 00000291F161BF40 nil toolchain C:\Program Files\xmake\toolchains\fpc nil nil +scope. table: 00000291F161B140 table: 00000291F161BB80 nil toolchain C:\Program Files\xmake\toolchains\nim nil nil +scope. table: 00000291F1A76AF0 table: 00000291F1621600 nil root nil nil zlua +scope. table: 00000291F1A77DB0 table: 00000291F1A76EF0 nil root.target nil nil nil +scope. table: 00000291F1A601F0 table: 00000291F1A5EB70 nil root nil nil zlua +scope. table: 00000291F1A61E70 table: 00000291F1A60C30 nil root.target nil nil nil +scope. table: 00000291F1A6B7B0 table: 00000291F1A6BDB0 nil package D:\zlua\thridpart\luasocket nil nil +scope. table: 00000291F1A6B7F0 table: 00000291F1A6BB30 nil package D:\zlua\thridpart\lua-protobuf nil nil +scope. table: 00000291F1A6E470 table: 00000291F1A6ED70 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\l\lua nil nil +scope. table: 00000291F1816600 table: 00000291F1816500 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\p\protobuf-cpp nil nil +scope. table: 00000291F1821500 table: 00000291F1820C00 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\c\cmake nil nil +scope. table: 00000291F195CB40 table: 00000291F195A940 nil root nil nil zlua +scope. table: 00000291F195D000 table: 00000291F195C000 nil root.target nil nil nil +scope. table: 00000291F1964F80 table: 00000291F195E040 nil target D:\zlua\src\clua nil nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua C:\Users\ouczbs\AppData\Local\.xmake\packages\l\lua\v5.4.4\200aae53e3a8489bb9f8fd764de1b658\include\lua +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp C:\Users\ouczbs\AppData\Local\.xmake\packages\p\protobuf-cpp\3.19.4\d949e9189ff94f2f8e4ad7b01f0219e4\include +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua C:\Users\ouczbs\AppData\Local\.xmake\packages\l\lua\v5.4.4\200aae53e3a8489bb9f8fd764de1b658\lib +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp C:\Users\ouczbs\AppData\Local\.xmake\packages\p\protobuf-cpp\3.19.4\d949e9189ff94f2f8e4ad7b01f0219e4\lib +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua C:\Users\ouczbs\AppData\Local\.xmake\packages\l\lua\v5.4.4\200aae53e3a8489bb9f8fd764de1b658\lib +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp C:\Users\ouczbs\AppData\Local\.xmake\packages\p\protobuf-cpp\3.19.4\d949e9189ff94f2f8e4ad7b01f0219e4\lib +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua lua +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp libprotobuf +package table: 00000291F19B4240 nil lua-protobuf nil +package table: 00000291F19B4300 nil lua nil +package table: 00000291F19B48C0 nil luasocket nil +package table: 00000291F19B4CC0 nil protobuf-cpp nil +package table: 00000291F19B4240 nil lua-protobuf nil +checking for release.x64 ... +scope. table: 00000291F16E72C0 table: 00000291F16E7180 nil toolchain C:\Program Files\xmake\toolchains\msvc nil nil +scope. table: 00000291F16EAB40 table: 00000291F16E9A80 nil toolchain C:\Program Files\xmake\toolchains\clang +nil nil +scope. table: 00000291F16EC080 table: 00000291F16EB3C0 nil toolchain C:\Program Files\xmake\toolchains\yasm nil nil +scope. table: 00000291F16EDE80 table: 00000291F16EDD00 nil toolchain C:\Program Files\xmake\toolchains\nasm nil nil +scope. table: 00000291F16F2040 table: 00000291F16F14C0 nil toolchain C:\Program Files\xmake\toolchains\cuda nil nil +scope. table: 00000291F16F3C80 table: 00000291F16F3D40 nil toolchain C:\Program Files\xmake\toolchains\rust nil nil +scope. table: 00000291F19DFDF0 table: 00000291F19E0030 nil toolchain C:\Program Files\xmake\toolchains\swift +nil nil +scope. table: 00000291F19E16F0 table: 00000291F19E1430 nil toolchain C:\Program Files\xmake\toolchains\go nil nil +scope. table: 00000291F19E4AB0 table: 00000291F19E47F0 nil toolchain C:\Program Files\xmake\toolchains\gfortran nil nil +scope. table: 00000291F19E6FB0 table: 00000291F19E6270 nil toolchain C:\Program Files\xmake\toolchains\zig nil nil +scope. table: 00000291F19E8930 table: 00000291F19E9070 nil toolchain C:\Program Files\xmake\toolchains\fpc nil nil +scope. table: 00000291F19EB9F0 table: 00000291F19EB770 nil toolchain C:\Program Files\xmake\toolchains\nim nil nil +scope. table: 00000291F19EC630 table: 00000291F19ECDB0 nil toolchain C:\Program Files\xmake\toolchains\msvc nil nil +checking for Microsoft Visual Studio (x64) version ... 2022 +scope. table: 00000291F140E920 table: 00000291F140E860 nil toolchain C:\Program Files\xmake\toolchains\clang +nil nil +scope. table: 00000291F1410320 table: 00000291F140F7A0 nil toolchain C:\Program Files\xmake\toolchains\yasm nil nil +scope. table: 00000291F140F760 table: 00000291F140F9E0 nil toolchain C:\Program Files\xmake\toolchains\nasm nil nil +scope. table: 00000291F140F9A0 table: 00000291F14100E0 nil toolchain C:\Program Files\xmake\toolchains\cuda nil nil +scope. table: 00000291F1411120 table: 00000291F140FB20 nil toolchain C:\Program Files\xmake\toolchains\rust nil nil +scope. table: 00000291F1411220 table: 00000291F1410CA0 nil toolchain C:\Program Files\xmake\toolchains\swift +nil nil +scope. table: 00000291F1411EE0 table: 00000291F1410B20 nil toolchain C:\Program Files\xmake\toolchains\go nil nil +scope. table: 00000291F1411BE0 table: 00000291F1411A60 nil toolchain C:\Program Files\xmake\toolchains\gfortran nil nil +scope. table: 00000291F1411620 table: 00000291F1411B60 nil toolchain C:\Program Files\xmake\toolchains\zig nil nil +scope. table: 00000291F14181E0 table: 00000291F1418420 nil toolchain C:\Program Files\xmake\toolchains\fpc nil nil +scope. table: 00000291F14194E0 table: 00000291F1417920 nil toolchain C:\Program Files\xmake\toolchains\nim nil nil +scope. table: 00000291F1568F20 table: 00000291F1566FE0 nil root nil nil zlua +scope. table: 00000291F156A660 table: 00000291F15688A0 nil root.target nil nil nil +scope. table: 00000291F149FFD0 table: 00000291F155AA20 nil root nil nil zlua +scope. table: 00000291F14A06D0 table: 00000291F149FB50 nil root.target nil nil nil +scope. table: 00000291F1492B90 table: 00000291F1492F90 nil package D:\zlua\thridpart\luasocket nil nil +scope. table: 00000291F1492110 table: 00000291F1492DD0 nil package D:\zlua\thridpart\lua-protobuf nil nil +scope. table: 00000291F1499850 table: 00000291F1499AD0 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\l\lua nil nil +scope. table: 00000291F130DB20 table: 00000291F130D6A0 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\p\protobuf-cpp nil nil +scope. table: 00000291F13225E0 table: 00000291F1322DE0 nil package C:\Users\ouczbs\AppData\Local\.xmake\repositories\xmake-repo\packages\c\cmake nil nil +scope. table: 00000291F1F1A160 table: 00000291F1F18C20 nil root nil nil zlua +scope. table: 00000291F1F1B1E0 table: 00000291F1F1A260 nil root.target nil nil nil +scope. table: 00000291F1608D80 table: 00000291F1F1C760 nil target D:\zlua\src\clua nil nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua C:\Users\ouczbs\AppData\Local\.xmake\packages\l\lua\v5.4.4\200aae53e3a8489bb9f8fd764de1b658\include\lua +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp C:\Users\ouczbs\AppData\Local\.xmake\packages\p\protobuf-cpp\3.19.4\d949e9189ff94f2f8e4ad7b01f0219e4\include +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua C:\Users\ouczbs\AppData\Local\.xmake\packages\l\lua\v5.4.4\200aae53e3a8489bb9f8fd764de1b658\lib +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp C:\Users\ouczbs\AppData\Local\.xmake\packages\p\protobuf-cpp\3.19.4\d949e9189ff94f2f8e4ad7b01f0219e4\lib +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua C:\Users\ouczbs\AppData\Local\.xmake\packages\l\lua\v5.4.4\200aae53e3a8489bb9f8fd764de1b658\lib +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp C:\Users\ouczbs\AppData\Local\.xmake\packages\p\protobuf-cpp\3.19.4\d949e9189ff94f2f8e4ad7b01f0219e4\lib +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua lua +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp libprotobuf +package table: 00000291F1F053E0 nil lua-protobuf nil +package table: 00000291F1F041E0 nil lua nil +package table: 00000291F1F047A0 nil luasocket nil +package table: 00000291F1F04DE0 nil protobuf-cpp nil +package table: 00000291F1F053E0 nil lua-protobuf nil \ No newline at end of file diff --git a/thridpart/luasocket/xmake.lua b/thridpart/luasocket/xmake.lua index 1d0cc0d..5bea0f0 100644 --- a/thridpart/luasocket/xmake.lua +++ b/thridpart/luasocket/xmake.lua @@ -6,9 +6,6 @@ target("luasocket") set_kind(kind) add_packages("lua") add_syslinks("ws2_32") - - - add_files("src/auxiliar.c","src/buffer.c","src/compat.c" ,"src/except.c" ,"src/inet.c") add_files("src/io.c","src/luasocket.c","src/options.c" ,"src/select.c" ,"src/tcp.c") add_files("src/timeout.c","src/udp.c","src/wsocket.c") diff --git a/xmake.lua b/xmake.lua index 076911c..57c817c 100644 --- a/xmake.lua +++ b/xmake.lua @@ -5,4 +5,5 @@ set_project("zlib") includes("thridpart/xmake.lua") includes("src") --xmake f -c ---xmake project -k vsxmake2022 -m "debug;release" \ No newline at end of file +--xmake project -k vsxmake2022 -m "debug;release" +