Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@

.vscode/*
iconbuster.py
form_test.py
*.bak
capdisasm.py
vtest*
namecollisions.py
62 changes: 46 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# IDA Scripts
Some random IDA scripts I wrote

### distfromfunc.py ###

### findmyfunc.py ###

Takes a SourceMod signature and jumps you to the function it's for. If it's a bad signature, then you won't go anywhere.

Get the offset from the cursor address and the start of a function. Useful for byte patching.

### gamedata_checker.py ###

Expand All @@ -18,25 +16,23 @@ Has a few quirks with it at the moment:
- Offset checking is variably difficult depending on naming conventions. If the gamedata key name is not named exactly the same as the function name, it will not be found; e.g. `OnTakeDamage` -> `CBaseEntity::OnTakeDamage` and `CTFPlayer::OnTakeDamage` -> `CBaseEntity::OnTakeDamage` but `TakeDamage` != `CBaseEntity::OnTakeDamage`.


### getfuncoffset.py ###

Get the offset from the cursor address and the start of a function. Useful for byte patching.


### isgoodsig.py ###

Takes a SourceMod signature input and detects if it's unique or not.
Takes a SourceMod (or any) signature input and detects if it's unique or not.


### makesig.py ###

Python translation of [makesig](https://github.com/alliedmodders/sourcemod/blob/master/tools/ida_scripts/makesig.idc).

Optionally, install pyperclip with `pip install pyperclip` to automatically copy any signatures to your clipboard when running.


### makesigfromhere.py ###

Creates a signature from the cursor offset. Useful for byte patching.


### nameresetter.py ###

Resets the name of every function in IDA's database. Does not include library or external functions.
Expand All @@ -46,15 +42,18 @@ Resets the name of every function in IDA's database. Does not include library or

Imports netprops and owner classes as structs and struct members into IDA's DB. Only works with the XML file provided by sm_dump_netprops_xml. Datatables only work most of the time. You should also use the proper netprop dump for your OS, or else you will be very confused.

You also have the option of importing vtables from the found classes into IDA. This is a bit more sane than the **vtable_structs.py** script, but only works on classes with netprops.

### sigfind.py ###

Takes a SourceMod (or any) signature and jumps you to the function it's for. If it's a bad signature, then you won't go anywhere.


### sigsmasher.py ###

Makes SourceMod ready signatures for every function in IDA's database. Yes, this will take a long, long time. Requires PyYAML so you'll need to `pip install pyyaml`. You have the option of only generating signatures for typed functions so this works very well with the Symbol Smasher.


### structaligner.py ###
### structfiller.py ###

Sanitizes undefined struct members as if IDA had parsed a header file. Each structure will have its undefined members replaced with a one-byte-sized member in order to prevent pseudocode from falling apart. Only makes sense to use it after running the netprop importer.

Expand All @@ -69,13 +68,44 @@ If you're on a symbol library, you should run it in read mode and export it to a

When on Windows or another stripped database, run the script in write mode and select the file you exported earlier. A solid amount of functions should be typed within a few seconds.

This works well with the Signature Smasher. However to save you an hour or so, I publicly host dumps of most Source games [here](https://brewcrew.tf/sigdump).
This works well with the Signature Smasher. However to save you an hour or so, I publicly host dumps of most Source games [here](http://scag.site.nfoservers.com/sigdump).

### vtable_io.py ###

Imports and exports virtual tables. Run it through a Linux binary to export to a file, then run it through a Windows binary to import those VTables into the database. This is similar to [Asherkin's VTable Dumper](https://asherkin.github.io/vtable/) but doesn't suffer from the pitfalls of multiple inheritance. Since it doesn't have those liabilities, it's function typing will almost always be perfect. 32-bit only for now.

Only works on libraries that have virtual thunks *after* the virtual table declaration such as in TF2. Fixing this is a TODO.
Imports and exports virtual tables. Run it through a Linux binary to export to a file, then run it through a Windows binary to import those VTables into the database. This is similar to [Asherkin's VTable Dumper](https://asherkin.github.io/vtable/) but doesn't suffer from the pitfalls of multiple inheritance. Since it doesn't have those liabilities, its function typing will almost always be perfect.

#### Features ####
This script is slightly heavy and has features that warrant explanation. Features can be freely enabled/disabled in the popup form that opens when you run the script. Desired features options are kept in the IDA registry and will persist.

**Parse type strings**
- Sometimes IDA fails to properly analyze Windows RTTI Type Descriptor objects. Because of this, there won't be a reference from certain type descriptors to std::type_info, which is required for the script to work.
- If this feature is enabled, then the string names of the type descriptor will be parsed in order to discover the unreferencing type descriptors. This will be done alongside the normal script function.
- If you notice that there are multiple functions of the same name or classes that have virtual functions that aren't typed, consider enabling this.
- It should be harmless to keep on regardless, but it is disabled by default.
- This problem only seemed to be present in NMRiH.

**Skip vtable size mismatches**
- The script is *almost* perfect. On rare occasion, it will fail to properly prepare a Windows translation of a Linux virtual table.
- If this option is enabled, then any size mismatches will forego function typing.
- Enabled by default.

**Comment reused functions**
- Windows oftentimes optimizes shorter and simpler functions and reuses them across multiple virtual tables. This means that it would be redundant to rename these functions over and over again.
- If enabled, virtual table declarations instead emplace a comment on the function's reference.
- Enabled by default.

**Export options**
- Should be self-explanatory, but the script is able to export the Linux and Windows virtual tables to a file.
- This is is a .json file and is organized to be readable.
- The format of the export file is as follows:
```json
"classname"
{
"[this-offset] vtable-offset function-name"
}
```
- Linux offsets are denoted with `L` and Windows with `W`. If the function is not present in a certain OS, then that index is empty.
- Exporting is optional, and if it is not enabled, then the export file path option can be safely ignored.

### vtable_structs.py ###

Expand Down
22 changes: 22 additions & 0 deletions distfromfunc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import idc
import idaapi

def main():
addr = idaapi.get_screen_ea()
if addr == idc.BADADDR:
print("Make sure you are in a function!")
idaapi.beep()
return

func = idaapi.get_func(addr)
if func is None:
print("Make sure you are in a function!")
idaapi.beep()
return

funcname = idaapi.get_name(func.start_ea)
demangled = idaapi.demangle_name(funcname, idc.get_inf_attr(idc.INF_SHORT_DN))
print(f"{demangled or funcname}:")
print(f"Offset from {func.start_ea:08X} to {addr:08X} = {addr - func.start_ea} ({addr - func.start_ea:#X})")

main()
17 changes: 0 additions & 17 deletions findmyfunc.py

This file was deleted.

Loading