-
Notifications
You must be signed in to change notification settings - Fork 449
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rather than use a heuristic to figure out if a thread is active, query the OS to see if the thread is running. This should provide a more accurate view on what's actually happening. The tricky part here is matching the OS thread id to the python thread id, which we were already doing for the native code unwinding. This refactors to allow getting the native thread id even when not getting the native stack.
- Loading branch information
Showing
17 changed files
with
783 additions
and
345 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
""" Generates the syscall.rs code """ | ||
import argparse | ||
import os | ||
import sys | ||
import json | ||
|
||
# We need to map to major/minor/build to the names used in the syscall table | ||
# https://www.gaijin.at/en/infos/windows-version-numbers | ||
OS_VERSION_LOOKUP = { | ||
("Windows Vista", "SP0"): (6, 0, 6000), | ||
("Windows Vista", "SP1"): (6, 0, 6001), | ||
("Windows Vista", "SP2"): (6, 0, 6002), | ||
("Windows 7", "SP0"): (6, 1, 7600), | ||
("Windows 7", "SP1"): (6, 1, 7601), | ||
("Windows 8", "8.0"): (6, 2, 9200), | ||
("Windows 8", "8.1"): (6, 3, 9600), | ||
("Windows 10", "1507"): (10, 0, 10240), | ||
("Windows 10", "1511"): (10, 0, 10586), | ||
("Windows 10", "1607"): (10, 0, 14393), | ||
("Windows 10", "1703"): (10, 0, 15063), | ||
("Windows 10", "1709"): (10, 0, 16299), | ||
("Windows 10", "1803"): (10, 0, 17134), | ||
("Windows 10", "1809"): (10, 0, 17763), | ||
("Windows 10", "1903"): (10, 0, 18362), | ||
} | ||
|
||
# I'm not supporting anything prior to vista here | ||
UNSUPPORTED_OS = {"Windows XP", "Windows Server 2003"} | ||
|
||
# these seem to have the same NT syscall as the consumer versions | ||
SERVER_OS = {"Windows Server 2008", "Windows Server 2012"} | ||
|
||
# how different are the syscall tables here? | ||
OS_SERVER_LOOKUP = { | ||
("Windows Server 2008", "SP0"): (6, 0, 6001), | ||
("Windows Server 2008", "SP2"): (6, 0, 6002), | ||
("Windows Server 2008", "R2"): (6, 1, 7600), | ||
("Windows Server 2012", "SP0"): (6, 2, 9200), | ||
("Windows Server 2012", "R2"): (6, 3, 9600), | ||
("Windows Server 2008", "R2 SP1"): (6, 1, 7601), | ||
} | ||
|
||
|
||
def generate(inputpath, arch="x64", namefilter=lambda s: not s.startswith("NtWait")): | ||
nt = json.load(open(os.path.join(inputpath, arch, "json", "nt-per-system.json"))) | ||
win32k = json.load(open(os.path.join(inputpath, arch, "json", "win32k-per-system.json"))) | ||
outputpath = os.path.dirname(os.path.realpath(__file__)) | ||
outputfilename = os.path.join(outputpath, f"syscalls_{arch}.rs") | ||
|
||
syscallnames = set() | ||
matches = [] | ||
|
||
for ((osname, osversion), (major, minor, build)) in OS_VERSION_LOOKUP.items(): | ||
syscalls = nt[osname][osversion] | ||
syscalls.update(win32k[osname][osversion]) | ||
for syscallname, syscallnumber in syscalls.items(): | ||
if namefilter and namefilter(syscallname): | ||
continue | ||
|
||
matches.append((major, minor, build, syscallnumber, syscallname)) | ||
syscallnames.add(syscallname) | ||
|
||
matches.sort() | ||
syscallnames = sorted(syscallnames) | ||
|
||
print(outputfilename) | ||
with open(outputfilename, "w") as o: | ||
o.write(f"// Automatically generated by '{__file__}' - do not edit\n") | ||
if namefilter: | ||
o.write("// Note that this is a subset of the syscalls, run again with no namefilter\n") | ||
o.write("// for the complete list (which takes forever to compile)\n") | ||
o.write("\n") | ||
o.write("#[allow(non_camel_case_types)]\n\n") | ||
|
||
o.write("pub enum Syscall {\n") | ||
for syscall in syscallnames: | ||
o.write(f" {syscall},\n") | ||
o.write("}\n\n") | ||
|
||
o.write("pub fn lookup_syscall(major: u32, minor: u32, build: u32, syscall: u32)") | ||
o.write(" -> Option<Syscall> {\n") | ||
o.write(" match (major, minor, build, syscall) {\n") | ||
for major, minor, build, syscallnumber, syscallname in matches: | ||
o.write(f" ({major}, {minor}, {build}, {syscallnumber})") | ||
o.write(f" => Some(Syscall::{syscallname}),\n") | ||
o.write(" _ => None\n") | ||
o.write(" }\n") | ||
o.write("}\n\n") | ||
|
||
|
||
if __name__ == "__main__": | ||
|
||
if sys.platform.startswith("win"): | ||
default_syscall_path = os.path.join(os.getenv("userprofile"), "code", "windows-syscalls") | ||
else: | ||
default_syscall_path = os.path.join(os.getenv("HOME"), "code", "windows-syscalls") | ||
|
||
parser = argparse.ArgumentParser( | ||
description="generates syscall.rs", formatter_class=argparse.ArgumentDefaultsHelpFormatter | ||
) | ||
parser.add_argument( | ||
"--syscallpath", | ||
type=str, | ||
default=default_syscall_path, | ||
dest="syscallpath", | ||
help="path to syscall repo https://github.com/j00ru/windows-syscalls", | ||
) | ||
args = parser.parse_args() | ||
|
||
if not os.path.isdir(args.syscallpath): | ||
print(f"Directory '{args.syscallpath}' doesn't exist!") | ||
print("Pass a valid path to the j00ru/windows-syscalls in with --syscallpath <pathname>") | ||
sys.exit(1) | ||
|
||
generate(args.syscallpath) |
Oops, something went wrong.
3ef940a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't actually work in all cases, still need a config file. idle select() calls are a good example. and poll() still shows up in my reports on windows