| 234 | } |
| 235 | |
| 236 | PackageResult package_shellcode(Span<std::uint8_t> shellcode, const PackageOptions& opt) { |
| 237 | SeedRng rng{opt.seed}; |
| 238 | |
| 239 | // range mode bounds check + lifter restriction |
| 240 | if (!opt.ranges.empty()) { |
| 241 | for (const auto& [s, e] : opt.ranges) { |
| 242 | if (e > shellcode.size) { |
| 243 | throw Error( |
| 244 | fmt::format( |
| 245 | "ranges entry 0x{:x}:0x{:x} extends past input size 0x{:x}", |
| 246 | s, |
| 247 | e, |
| 248 | static_cast<std::uint32_t>(shellcode.size) |
| 249 | ) |
| 250 | ); |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | if (opt.verbose) { |
| 255 | std::fprintf(stderr, "ranges hybrid mode: %zu range/s\n", opt.ranges.size()); |
| 256 | for (const auto& [s, e] : opt.ranges) { |
| 257 | std::fprintf( |
| 258 | stderr, |
| 259 | " va 0x%x..0x%x %u bytes\n", |
| 260 | s, |
| 261 | e, |
| 262 | e - s |
| 263 | ); |
| 264 | } |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | // pack + ranges: build the range-mode blob first then pack-wrap it |
| 269 | if (opt.pack_mode && !opt.ranges.empty()) { |
| 270 | PackageOptions inner = opt; |
| 271 | inner.pack_mode = false; // inner pass: just range-mode |
| 272 | auto inner_pkg = package_shellcode(shellcode, inner); |
| 273 | PackageOptions outer = opt; |
| 274 | outer.ranges.clear(); // outer pass: pure pack |
| 275 | Span<std::uint8_t> inner_bytes{inner_pkg.blob.data(), static_cast<std::uint32_t>(inner_pkg.blob.size())}; |
| 276 | |
| 277 | auto outer_pkg = package_shellcode(inner_bytes, outer); |
| 278 | outer_pkg.stats = fmt::format( |
| 279 | "{}\n pack+ranges chain: inner range-mode blob = {} B", |
| 280 | outer_pkg.stats, inner_pkg.blob.size() |
| 281 | ); |
| 282 | |
| 283 | return outer_pkg; |
| 284 | } |
| 285 | |
| 286 | // lift |
| 287 | CFGBuilder cfg{opt.arch, shellcode, opt.base_va}; |
| 288 | IRProgram prog; |
| 289 | if (opt.pack_mode) { |
| 290 | // single synthetic JMP_NATIVE |
| 291 | prog.arch = opt.arch; |
| 292 | prog.entry_va = opt.base_va; |
| 293 | IRBlock blk; |
no test coverage detected