~ all posts ctf projects
417 words
2 minutes
TextMate grammar for Binary Ninja HLIL
2024-07-16
No Tags

I display a lot of decompiled code in my blog when writing up research on compiled binaries. Over the years I’ve bounced between screenshots (pain in the ass) to copied HLIL/pseudo-c without address (loses valuable context but looks pretty) to HLIL/pseudo-c (easy, highlights kinda ugly).

This isn’t particularly high-quality or production grade code — it was the result of an afternoon yak shave that was Good Enough for my use case and I haven’t thought about it since — I mention it here because of marginally higher discovery on my blog than a random GitHub repo.

you can find it here :) do let me know if there are any edge cases or low hanging fruit improvements that would help your use case and I’d be happy to work on it more.

before (highlighted as c)#

1
000011a9 void* clap(int64_t arg1, int64_t arg2)
2
3
000011eb *(arg1 + &data) = *(arg1 + &data) ^ *(arg2 + &data)
4
0000121f *(arg2 + &data) = *(arg2 + &data) ^ *(arg1 + &data)
5
00001253 *(arg1 + &data) = *(arg1 + &data) ^ *(arg2 + &data)
6
00001257 return arg1 + &data
7
8
00001258 int32_t main(int32_t argc, char** argv, char** envp)
9
10
00001264 void* fsbase
11
00001264 int64_t rax = *(fsbase + 0x28)
12
0000127d puts(str: &__art)
13
0000128c puts(str: "\x1b[0;33mEven this cursed spiri…")
14
00001303 while (data != 0)
15
00001293 int64_t var_18 = 0
16
000012b4 printf(format: "\n\x1b[31;49;1;4m%s\x1b[0m\n\n\n", &data)
17
000012c3 puts(str: "The sound of \x1b[0;33mgion shoj…")
18
000012e2 int64_t var_20
19
000012e2 __isoc99_scanf(format: "%zu %zu", &var_20, &var_18)
20
000012f5 clap(var_20, var_18)
21
0000130e *(fsbase + 0x28)
22
00001317 if (rax == *(fsbase + 0x28))
23
0000131f return 0
24
00001319 __stack_chk_fail()
25
00001319 noreturn

after (highlighted as hlil)#

1
000011a9 void* clap(int64_t arg1, int64_t arg2)
2
3
000011eb *(arg1 + &data) = *(arg1 + &data) ^ *(arg2 + &data)
4
0000121f *(arg2 + &data) = *(arg2 + &data) ^ *(arg1 + &data)
5
00001253 *(arg1 + &data) = *(arg1 + &data) ^ *(arg2 + &data)
6
00001257 return arg1 + &data
7
8
00001258 int32_t main(int32_t argc, char** argv, char** envp)
9
10
00001264 void* fsbase
11
00001264 int64_t rax = *(fsbase + 0x28)
12
0000127d puts(str: &__art)
13
0000128c puts(str: "\x1b[0;33mEven this cursed spiri…")
14
00001303 while (data != 0)
15
00001293 int64_t var_18 = 0
16
000012b4 printf(format: "\n\x1b[31;49;1;4m%s\x1b[0m\n\n\n", &data)
17
000012c3 puts(str: "The sound of \x1b[0;33mgion shoj…")
18
000012e2 int64_t var_20
19
000012e2 __isoc99_scanf(format: "%zu %zu", &var_20, &var_18)
20
000012f5 clap(var_20, var_18)
21
0000130e *(fsbase + 0x28)
22
00001317 if (rax == *(fsbase + 0x28))
23
0000131f return 0
24
00001319 __stack_chk_fail()
25
00001319 noreturn

use in astro#

astro.config.mjs
1
// pnpm add tsheinen/tm_hlil
2
import { defineConfig } from 'astro/config';
3
import { hlil } from 'tm_hlil';
4
5
// https://astro.build/config
6
export default defineConfig({
7
site: 'https://example.com',
8
markdown: {
9
shikiConfig: {
10
langs: [hlil]
11
}
12
}
13
});