Skip to content

Commit 1dbf407

Browse files
authored
Merge pull request Scags#2 from Scags/refactor
Refactor
2 parents 125f187 + 4099677 commit 1dbf407

18 files changed

Lines changed: 2965 additions & 1307 deletions

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11

22
.vscode/*
33
iconbuster.py
4+
form_test.py
5+
*.bak
6+
capdisasm.py
7+
vtest*
8+
namecollisions.py

README.md

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
# IDA Scripts
22
Some random IDA scripts I wrote
33

4+
### distfromfunc.py ###
45

5-
### findmyfunc.py ###
6-
7-
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.
8-
6+
Get the offset from the cursor address and the start of a function. Useful for byte patching.
97

108
### gamedata_checker.py ###
119

@@ -18,25 +16,23 @@ Has a few quirks with it at the moment:
1816
- 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`.
1917

2018

21-
### getfuncoffset.py ###
22-
23-
Get the offset from the cursor address and the start of a function. Useful for byte patching.
24-
25-
2619
### isgoodsig.py ###
2720

28-
Takes a SourceMod signature input and detects if it's unique or not.
21+
Takes a SourceMod (or any) signature input and detects if it's unique or not.
2922

3023

3124
### makesig.py ###
3225

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

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

3631
### makesigfromhere.py ###
3732

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

35+
4036
### nameresetter.py ###
4137

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

4743
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.
4844

49-
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.
45+
46+
### sigfind.py ###
47+
48+
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.
5049

5150

5251
### sigsmasher.py ###
5352

5453
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.
5554

5655

57-
### structaligner.py ###
56+
### structfiller.py ###
5857

5958
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.
6059

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

7069
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.
7170

72-
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).
71+
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).
7372

7473
### vtable_io.py ###
7574

76-
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.
77-
78-
Only works on libraries that have virtual thunks *after* the virtual table declaration such as in TF2. Fixing this is a TODO.
75+
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.
76+
77+
#### Features ####
78+
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.
79+
80+
**Parse type strings**
81+
- 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.
82+
- 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.
83+
- 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.
84+
- It should be harmless to keep on regardless, but it is disabled by default.
85+
- This problem only seemed to be present in NMRiH.
86+
87+
**Skip vtable size mismatches**
88+
- The script is *almost* perfect. On rare occasion, it will fail to properly prepare a Windows translation of a Linux virtual table.
89+
- If this option is enabled, then any size mismatches will forego function typing.
90+
- Enabled by default.
91+
92+
**Comment reused functions**
93+
- 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.
94+
- If enabled, virtual table declarations instead emplace a comment on the function's reference.
95+
- Enabled by default.
96+
97+
**Export options**
98+
- Should be self-explanatory, but the script is able to export the Linux and Windows virtual tables to a file.
99+
- This is is a .json file and is organized to be readable.
100+
- The format of the export file is as follows:
101+
```json
102+
"classname"
103+
{
104+
"[this-offset] vtable-offset function-name"
105+
}
106+
```
107+
- 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.
108+
- Exporting is optional, and if it is not enabled, then the export file path option can be safely ignored.
79109

80110
### vtable_structs.py ###
81111

distfromfunc.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import idc
2+
import idaapi
3+
4+
def main():
5+
addr = idaapi.get_screen_ea()
6+
if addr == idc.BADADDR:
7+
print("Make sure you are in a function!")
8+
idaapi.beep()
9+
return
10+
11+
func = idaapi.get_func(addr)
12+
if func is None:
13+
print("Make sure you are in a function!")
14+
idaapi.beep()
15+
return
16+
17+
funcname = idaapi.get_name(func.start_ea)
18+
demangled = idaapi.demangle_name(funcname, idc.get_inf_attr(idc.INF_SHORT_DN))
19+
print(f"{demangled or funcname}:")
20+
print(f"Offset from {func.start_ea:08X} to {addr:08X} = {addr - func.start_ea} ({addr - func.start_ea:#X})")
21+
22+
main()

findmyfunc.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)