intelligence_src_f9879f264b7a8ec1d7
- Source-provided label
- Publisher RSS metadata
- Evidence class
- mentioned in report
- Confidence
- Not reported
- Observed
- Oct 12, 2026 05:26 UTC
- Retrieved
- Oct 13, 2026 05:17 UTC
﷽ Introduction to Malware Binary Triage (IMBT) Course Looking to level up your skills? Get 10% off using coupon code: MWNEWS10 for any flavor. Enroll Now and Save 10%: Coupon Code MWNEWS10 Note: Affiliate link – your enrollment helps support this platform at no extra cost to you. Hello, cybersecurity enthusiasts and white hackers! In part 1 we reversed the WAMR .aot container from real bytes and wrote unaot - a tiny, dependency-free C parser that verifies the \0aot magic, walks the section table (handling the 4-byte alignment rule), and decodes TARGET_INFO so we know exactly which CPU the embedded TEXT blob is compiled for. That told us where the native code is and how to disassemble it. But a disassembly of a few hundred anonymous functions is nearly useless. What a reverse engineer actually wants is names: which blob of machine code is add, which is fib, which is the exported entry point. This part builds exactly that - a symbolized function table - by decoding two more sections, EXPORT and FUNCTION, and joining them. We will also give the tool some color so the output is readable. Still one small C file, still no libraries. the plan The information we need is split across two sections, and neither one is enough on its own: FUNCTION gives us, for every defined function, the offset into TEXT where its native code starts (and its type index). It gives us the geography - but no names. EXPORT gives us names mapped to function indices - but no offsets. The two share a key: the function index. So the whole trick of part 2 is: Decode both, join on the index, and we have a symbol table that maps every native function to a name and a precise file offset. Let’s take the sections one at a time. the EXPORT section EXPORT is the name source. Its layout (from WAMR’s aot_loader.c, load_export_section) is a count followed by that many export entries: u32 count entry[count]: u32 index (4-byte aligned) u8 kind 0=func 1=table 2=memory 3=global 4=tag str name The one part that will trip you up is how WAMR stores a string. It is not a plain C string and not a bare length-prefixed buffer. It is: u16 length (2-byte aligned) u8 bytes[length] <- the trailing '\0' IS counted in length So a name like add is stored with length = 4: the three characters a, d, d, plus a trailing NUL that is included in the count. If you print length bytes you get a stray NUL at the end; if you assume the length excludes the terminator you read one byte short on the next field and desync. We copy length bytes and then drop the last one. Here is decode_export. Note the two alignment steps - index is 4-aligned, the string length is 2-aligned - mirroring the loader’s alignment-aware reads from part 1: /* EXPORT: u32 count, then { u32 index(align4), u8 kind, string name }. * string = u16 len(align2) + len bytes (trailing '\0' counted in len). */ static void decode_export(reader_t *r, size_t body, uint32_t size) { size_t end = body + size, pos = body; uint32_t count = rd_u32_at(r, pos); pos += 4; if (r->err) { printf(" <export truncated>\n"); return; } printf(" %u export(s):\n", count); for (uint32_t i = 0; i < count; i++) { pos = align_up(pos, 4); uint32_t index = rd_u32_at(r, pos); pos += 4; uint8_t kind = rd_u8_at(r, pos); pos += 1; pos = align_up(pos, 2); uint16_t slen = rd_u16_at(r, pos); pos += 2; if (r->err || pos + slen > end) { printf(" <export %u truncated>\n", i); break; } char name[96]; size_t n = slen < sizeof(name) ? slen : sizeof(name) - 1; for (size_t j = 0; j < n; j++) name[j] = (char) rd_u8_at(r, pos + j); name[n ? n - 1 : 0] = 0; /* drop the counted trailing '\0' */ pos += slen; printf(" [%u] %-6s index=%-3u \"%s\"\n", i, export_kind_name(kind), index, name); if (kind == 0 && g_expn < MAXF) { /* remember func names for symbolization */
452d77af24c5b6379acccf3ba0b0e1d2f10dc2afd6efd9a2c842f9c76c48a82aNetwork indicators are visibly defanged. This page does not make them clickable or send them to another service.
No validated file hashes or network indicators are stored for this record.
This record contains metadata and attribution only. It does not host, download, unpack, render, or execute malware samples.
Sources represented on this page. Publication and observation dates describe the content; successful batch dates describe local collection. A recent batch does not certify complete coverage or current provider availability.
1 sources: 0 stale, 0 needing attention, 0 paused, 0 unverified.
Stale means older than twice the recorded collection interval, with a minimum of one hour; without an interval, the threshold is 24 hours. Cached content remains available while a feed is stale, paused, or unverified.