This project is meant to make life easier when reversing linux kernel/modules/cpp binaries without debug information.
- Windows WSL installed.
- Download the examples.zip from IDA website.,
unzipandcdto it. - You should also have
idaclang.exe,libclang.dll,ida.hlpfrom IDA Pro, andtilib64.exefrom IDA SDK. They are NOT provided in this repo and figure it out for yourself.
The folder should be like:
.
├── README.MD
├── ida.hlp
├── idaclang.exe
├── idaclang.mak
├── libclang.dll
├── linux
│ ├── linux.h
│ ├── linux_kernel_4_9.mak
│ ├── linux_kernel_5_11.mak
│ ├── linux_kernel_5_4.mak
│ ├── linux_kernel_5_4.til
│ ├── linux_kernel_5_4.til.txt
│ └── lkm_example
├── linux-headers
│ ├── kernel-headers
│ ├── system-headers
│ ├── usr_include_headers
│ └── usr_lib_headers
├── stl
│ ├── Makefile
│ ├── libstl_cpp.log
│ ├── libstl_cpp.mak
│ ├── libstl_cpp.til
│ ├── libstl_cpp.til.txt
│ ├── stl_example.h
│ └── stl_example.py
├── tilib64.exe
The .exe in Windows cannot read WSL filesystem with /usr/src/xxx path, so we have to copy the system and kernel headers to Windows filesystem. For example:
mkdir linux-headers
cd linux-headers
cp -LR /usr/src/linux-headers-5.4.0-159-generic/ kernel-headers/
cp -LR /usr/lib/gcc/x86_64-linux-gnu/9/include system-headers/
cp -LR /usr/include libc_headers/ usr_include_headers/Don't forget to use -L option in cp to handle the symbolic/soft links correctly.
Change the ldaclang.mak to call Windows binaries from WSL:
IDACLANG_ARGS += --idaclang-log-all
IDACLANG_ARGS += --idaclang-tilname $(TIL_NAME)
IDACLANG_ARGS += --idaclang-tildesc $(TIL_DESC)
CLANG_ARGV += -ferror-limit=200
all: $(TIL_NAME)
.PHONY: all $(TIL_NAME) clean
$(TIL_NAME): $(TIL_NAME).til
$(TIL_NAME).til: $(TIL_NAME).mak $(INPUT_FILE)
/mnt/c/Users/hp/Desktop/se/kernel/examples/idaclang.exe $(IDACLANG_ARGS) $(CLANG_ARGV) $(INPUT_FILE) > $(TIL_NAME).log
/mnt/c/Users/hp/Desktop/se/kernel/examples/tilib64.exe -ls $(TIL_NAME).til > $(TIL_NAME).til.txt
clean:
rm -rf *.til *.txt *.log
Write a linux_kernel_5_4.mak to include all the required headers:
#include <linux/kconfig.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/fs.h>
#include <linux/efi.h>
#include <linux/bpf.h>
#include <linux/usb.h>
#include <linux/kmod.h>
#include <linux/device.h>
#include <linux/blkdev.h>Then write the makefile as follows:
TIL_NAME = linux_kernel_5_4
TIL_DESC = "Linux kernel headers for 5.4.0-159-generic"
INPUT_FILE = linux.h
SYSTEM_HEADERS = C:\Users\hp\Desktop\se\kernel\examples\linux-headers\system-headers
KERNEL_HEADERS = C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers
CLANG_ARGV = -target x86_64-pc-linux-gnu \
-nostdinc \
-isystem "$(SYSTEM_HEADERS)" \
-I"$(KERNEL_HEADERS)\arch\x86\include" \
-I"$(KERNEL_HEADERS)\arch\x86\include\generated" \
-I"$(KERNEL_HEADERS)\include" \
-I"$(KERNEL_HEADERS)\arch\x86\include\uapi" \
-I"$(KERNEL_HEADERS)\arch\x86\include\generated\uapi" \
-I"$(KERNEL_HEADERS)\include\uapi" \
-I"$(KERNEL_HEADERS)\include\generated\uapi" \
-D__KERNEL__ \
-O2 \
-mfentry \
-DCC_USING_FENTRY \
-Wno-gnu-variable-sized-type-not-at-end
include ../idaclang.makThen just run the make command:
$ make -f linux_kernel_5_4.mak
/mnt/c/Users/hp/Desktop/se/kernel/examples/idaclang.exe --idaclang-log-all --idaclang-tilname linux_kernel_5_4 --idaclang-tildesc "Linux kernel headers for 5.4.0-159-generic" -target x86_64-pc-linux-gnu -nostdinc -isystem "C:\Users\hp\Desktop\se\kernel\examples\linux-headers\system-headers" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\arch\x86\include" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\arch\x86\include\generated" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\include" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\arch\x86\include\uapi" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\arch\x86\include\generated\uapi" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\include\uapi" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\kernel-headers\include\generated\uapi" -D__KERNEL__ -O2 -mfentry -DCC_USING_FENTRY -Wno-gnu-variable-sized-type-not-at-end -ferror-limit=50 linux.h > linux_kernel_5_4.log
/mnt/c/Users/hp/Desktop/se/kernel/examples/tilib64.exe -ls linux_kernel_5_4.til > linux_kernel_5_4.til.txtThe generated type library is .til and you can check the structures it generated in .til.txt.
Similarly, write a header including possibel types first, for example:
#include <string>
#include <vector>
#include <map>
#include <set>
struct stl_example_t
{
std::string str;
std::vector<int> vec;
std::map<std::string, int> map;
std::set<char> set;
};And the makefile:
TIL_NAME = libstl_cpp
TIL_DESC = "Linux stl"
INPUT_FILE = stl_example.h
SYSTEM_HEADERS = C:\Users\hp\Desktop\se\kernel\examples\linux-headers\system-headers
USR_INCLUDE_HEADERS = C:\Users\hp\Desktop\se\kernel\examples\linux-headers\usr_include_headers
CLANG_ARGV = -target x86_64-pc-linux-gnu \
-x c++ \
-I"$(SYSTEM_HEADERS)" \
-I"$(USR_INCLUDE_HEADERS)\include\linux" \
-I"$(USR_INCLUDE_HEADERS)\include\c++\9" \
-I"$(USR_INCLUDE_HEADERS)\include\x86_64-linux-gnu" \
-I"$(USR_INCLUDE_HEADERS)\include\x86_64-linux-gnu\c++\9" \
-I"$(USR_INCLUDE_HEADERS)\include"
include ../idaclang.makNote that you shoule modify the compiler version number (the "9"s in the above example) to your local version.
Run:
$ make -f libstl_cpp.mak all
/mnt/c/Users/hp/Desktop/se/kernel/examples/idaclang.exe --idaclang-log-all --idaclang-tilname libstl_cpp --idaclang-tildesc "Linux stl" -target x86_64-pc-linux-gnu -x c++ -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\system-headers" -I"C:\Users\hp\Desktop\se\esktop\se\kernel\examples\linux-headers\usr_include_headers\include\linux" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\usr_include_headers\include\c++\9" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\usr_include_headers\include\x86_64-liI"C:\Usersnux-gnu" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\usr_include_headers\include\x86_64-linux-gnu\c++\9" -I"C:\Users\hp\Desktop\se\kernel\examples\linux-headers\usr_include_headers\include" -ferror-limit=200 stl_example.h > libstl_cpp.log
/mnt/c/Users/hp/Desktop/se/kernel/examples/tilib64.exe -ls libstl_cpp.til > libstl_cpp.til.txt- Put the
.tilto yourIDA_INSTALL_LOCATION\til\pc\ - In IDA, hit
Shift+F11to open the type library window and choose the generated lib. - Now check the
Local Typestab and you will see all the structures. - There maybe some errors for the imported structures (IDK why but seems to be size-calculation error). Just just manually repair the empty structs with content from .til.txt, for example in my case:
struct mutex
{
atomic_long_t owner;
spinlock_t wait_lock;
optimistic_spin_queue osq;
list_head wait_list;
};
struct fown_struct
{
rwlock_t lock;
pid *pid;
pid_type pid_type;
kuid_t uid;
kuid_t euid;
int signum;
};If you have any better solutions or problems, PR/issues please :).
- [1] Using the IDAClang plugin for IDA Pro https://hex-rays.com/tutorials/idaclang/
- [2] Type libraries in IDA: https://hex-rays.com/blog/igors-tip-of-the-week-60-type-libraries/