Repository navigation
doc: rewrite the docs and code comments in simplified English - #498
Merged
Merged
Conversation
Replace the README documentation map with a link to doc/index.md, which already lists all pages; the two lists had diverged. In architecture.md, remove the config defaults, the WOW64 API list, the relocation types and the _handle_api_* method list. The config, the handlers and the docstrings already have these details. Remove the edge cases of dropped DLLs in child processes. State once that a hook records a native exit and does not run handlers. In both files, reword sentences so that the subject is the part that does the action.
Reword the doc pages so that the subject of each sentence does the action, name the referent of each "it" and "this", and replace vague verbs. Remove copied counts, defaults and lists that go stale, and convert short bullet lists and one-line sections to prose. Fix claims that do not match the code: - reporting: the report leaves out unknown keys instead of null; dropped_files and memory are user-mode only; Speakeasy never emits module_load. - configuration: the stack_size default, the meaning of $ROOT$, the winsock default response, and --volume in the precedence order. - cli-reference: the flag naming rule for repeated words and hex input for integer flags. - gdb: the server reports module unloads; add vKill. - cli-execution-controls: the collectors behind the --no-* flags are off by default; a child process is skipped on any load error. - memory: the format of memory tags. - limitations and api-handlers: unsupported API conditions and the handler aliases. - speakeasy2-walkthrough: the memory layout is in every report; automatic volumes apply only to load_module with a path. Rename the walkthrough to "What's new in Speakeasy 2.0".
…comments The docstring of dispatch_fault said that it returns False when no handler takes the exception. It returns False only when the dispatch fails before it calls a guest handler. A later failure ends the run.
The docstring of get_import_slots said that the function skips a descriptor that it cannot read. The function stops at such a descriptor. It skips only a descriptor without a valid DLL name.
The class docstring said that peb_addr is the address of the PEB. It is the address of the PEB pointer in the TEB, and only Win32Emulator sets it.
The docstring of create_reg_path said that it creates a key in the registry. It only writes the path string to guest memory.
Fix false comments. get_pack said that the default pack is the pointer size, but the code returns twice the pointer size. get_bytes said that it respects endianness, but it copies the host memory. The __init__ comment said that a __dict__ write prevents a __getattribute__ loop, but __setattr__ raises AttributeError before __struct__ exists.
The module docstring said that dispatch_fault is a generator handler. It returns a bool.
A comment said that file_open deep-copies a file. The copy shares the data and has its own file pointer. A comment said that file_config is the "files" key of the config. It is the filesystem section.
The module docstring said that dispatch_fault is a generator handler. It returns a bool.
The docstring of _prepare_next_run said that it runs the next run. It only prepares the next run; the run loop starts Unicorn.
The docstring of get_key_paths said that it gives the open keys. It gives all known keys, open or not. A comment said that get_key_handle creates a key only on request. It also creates a key that is the parent of a known key.
The docstring of SessionManager said that it isolates sessions. The emulator has one session and no isolation.
The module docstring said that the emulator calls this module only from four places. The emulator and the SEH code also call start, fail, alloca and caller_context. The comment on HandlerState.context said CONTEXT64, but on x86 the field holds the address of an x86 CONTEXT.
The docstring said that the class removes a load when a DllMain returns FALSE. It does this only in LoadLibrary. A failed initializer at start keeps its module mapped with the state INIT_ERROR.
The docstrings said that a handle table belongs to a process. The managers for sockets, windows and crypto objects also have tables.
The docstring of set_hooks said that it reserves memory. It adds the hooks of the hook lists to Unicorn.
Fix false docstrings. A native hook calls its callback through a wrapper such as _wrap_code_cb, and a hook that is not native goes through a dispatch hook of the emulator; the docstring said the reverse. A dynamic code hook can fire more than once for a region: it also fires when code in the region calls an API.
The docstring said that the hook fires for generated or copied code. The hook fires for code in memory that VirtualAlloc or a similar API allocated.
Fix a false comment. The register list said that Unicorn does not give the x87 segment selectors or the operand offset, but Unicorn 2.1 has UC_X86_REG_FCS, UC_X86_REG_FDS and UC_X86_REG_FDP. The comment now tells what the server does: it gives 0 for these registers.
The stack_size description said that 0 uses SizeOfStackReserve or 0x12000. For a PE, the loader uses max(SizeOfStackReserve, 0x12000). For shellcode, run_shellcode uses its stack_commit argument (default 0x4000). The max_instructions description did not say that 0 or less disables the limit.
The --dropped-files-path help said that the path stores the files. The CLI writes one zip archive with a speakeasy_manifest.json to the path. The --emulate-children help named only CreateProcess, and did not say that it applies only to PE input.
The docstring of _handle_invalid_write said that the hook runs for a write to a non-writable address. It runs for a write to unmapped memory. A comment said that the hook ignores patches to APIs, but the reserved range has the return addresses of the emulator, not the code of APIs.
The get_run_time docstring said that the method gives the time of one run. The method gives the time since the last call of set_start_time. The record_api_event docstring said that the event has the return address. The event has the pc of the call.
The add_hook docstring said that all hooks of a type run and that only IN hooks are an exception. Invalid memory hooks stop on False, invalid instruction hooks stop on True, and an API without a handler runs only the last hook. The do_call_return comment said that the engine removes the cdecl arguments. The caller removes them.
The comment on the export runs said that the emulator stores them and queues them only before the unload routine. add_run adds each export run to the queue at once, after the DllMain run.
The TYPE_SIZES comment said that ParamSig.size gives the size of ps:NAME. ps is pointer-sized in TYPE_SIZES. ParamSig.size computes only st and arr.
The comment on the export runs said that the emulator queues them just before the unload routine. next_driver_func queues them when the run queue is empty after DriverEntry, before the first IRP run.
…nd the objects The comment of get_module_data_from_emu_file said that it creates a module. It only returns the contents of the file.
The ToggleableHook docstring said that the hook can be toggled. The engine does not read its enabled flag; the Hook objects in common check their own flag. The class keeps the ctypes callback alive.
The event descriptions said how to use each event, and some were false. ProcessCreateEvent.pid said that the target may differ from the new process. MemProtectEvent said that more than one API records it; only VirtualProtectEx records it. FileReadEvent.size said 'requested/read'; the profiler adds the number of bytes read. Regenerate the report schema.
The descriptions said how to use each field, and some were false. ErrorInfo.count said that the value is the API call count. The value is the limit: max_api_calls for max_api_count, and the instruction limit for max_instructions. Report.emulation_total_runtime and Report.timestamp said that the clock starts at the start of the emulation. The clock starts again each time the emulator starts the run queue. Regenerate the report schema.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR rewrites the README, the pages in
doc/and the comments and docstrings of the core modules in ASD-STE100 style. The sentences put the actor first and use active verbs. I removed vague verbs, unclear "it" and "this" references, notes about earlier changes, and lists of details that go out of date. The PR also corrects about 25 statements indoc/that did not agree with the code. Examples are thestack_sizedefault, the meaning of$ROOT$, the GDBvKillbehavior and the report keys that can be null or absent.The code has the same behavior. In each changed
.pyfile, an AST comparison againstmastershows changes only in docstrings, comments anddescription=/help=strings. The one other change is two module constants inconfig.py, so that three Field definitions share one description each. The CLI--helptext, the config field descriptions and the report field descriptions are user-visible. I regeneratedspeakeasy/resources/report.schema.json, and only its descriptions changed. ruff and mypy pass.The review also found code defects. This PR does not fix them. #499 tracks them, with one sub-issue for each defect.
🤖 Generated with Claude Code