Skip to content
Draft
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
42 changes: 42 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Lint

on:
pull_request:
branches: [ main ]

jobs:
lint:
strategy:
fail-fast: false
matrix:
linter: [
{"name": "tests-flake8", "format": "flake8", "cwd": ".", "cmd": "flake8 tests"},
{"name": "tests-mypy", "format": "mypy", "cwd": ".", "cmd": "mypy tests"},
{"name": "tests-pylint", "format": "pylint-json", "cwd": ".", "cmd": "pylint --load-plugins pylint_pytest $(Get-ChildItem -Filter *.py -Recurse tests)"},
{"name": "eslint", "format": "eslint-unix", "cwd": "bugalua", "cmd": "node_modules\\.bin\\eslint.ps1 --format=unix ."},
]
name: ${{ matrix.linter.name }}
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r tests\dev-requirements.txt
python -m pip install git+https://github.com/bugale/Bugalintly.git@bugalintly
- name: Install Node.JS dependencies
run: |
cd bugalua
npm install .
- name: Lint
run: |
cd ${{ matrix.linter.cwd }}
${{ matrix.linter.cmd }} > lint.log
$exitcode = $LASTEXITCODE
type lint.log | Lintly --log --no-request-changes --no-review-body --base-dir .. --format=${{ matrix.linter.format }} --comment-tag=${{ matrix.linter.name }}
exit $exitcode
env:
LINTLY_API_KEY: ${{ secrets.GITHUB_TOKEN }}
29 changes: 29 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Test

on:
pull_request:
branches: [ main ]

jobs:
test:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install Windows SDK 22621
run: |
Invoke-WebRequest -UseBasicParsing -Uri 'https://go.microsoft.com/fwlink/p/?linkid=2196241' -OutFile 'winsdksetup.exe'
Start-Process -Wait '.\winsdksetup.exe' '/features OptionId.WindowsDesktopDebuggers /quiet /norestart'
Remove-Item -Force 'winsdksetup.exe'
- name: Install Bugalua
run: |
.\Install.ps1
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r tests\requirements.txt
- name: Test
run: |
pytest tests
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**\__pycache__
**\package-lock.json
**\node_modules
18 changes: 18 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.linting.flake8Args": [],
"python.linting.mypyEnabled": true,
"python.linting.mypyArgs": ["--follow-imports=silent"],
"python.linting.pylintEnabled": true,
"python.linting.pylintArgs": ["--load-plugins", "pylint_pytest"],
"python.testing.pytestEnabled": true,
"eslint.enable": true,
"files.associations": {
"*.yaml": "home-assistant"
},
"editor.tabSize": 4,
"[javascript]": {
"editor.tabSize": 2
}
}
5 changes: 5 additions & 0 deletions Install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
param ($windbgPath='C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe')
(Get-Content $PSScriptRoot\Manifest\config.xml) -Replace [regex]::escape('C:\the\path\to\this\repo'), "$PSScriptRoot" | Set-Content $PSScriptRoot\Manifest\config.xml
$TempFile = New-TemporaryFile
".settings load $PSScriptRoot\Manifest\config.xml`n.settings save`nqq`n" | Out-File -Encoding ASCII $TempFile
& "$windbgPath" "-c" "$<$TempFile" "C:\Windows\system32\cmd.exe"
24 changes: 24 additions & 0 deletions Manifest/Manifest.1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version='1.0' encoding='utf-8'?>
<ExtensionPackages Version='1.0.0.0' Compression='none'>
<ExtensionPackage>
<Name>Bugalua</Name>
<Version>1.0.0.0</Version>
<Description>Lua debugging extension</Description>
<Components>
<ScriptComponent Name='Bugalua' Type='Engine' File='..\bugalua\bugalua.js' FilePathKind='RepositoryRelative'>
<FunctionAliases>
<FunctionAlias Name='lua'>
<AliasItem>
<Syntax>
<![CDATA[!lua <address>]]>
</Syntax>
<Description>
<![CDATA[Lua state inspection.]]>
</Description>
</AliasItem>
</FunctionAlias>
</FunctionAliases>
</ScriptComponent>
</Components>
</ExtensionPackage>
</ExtensionPackages>
3 changes: 3 additions & 0 deletions Manifest/ManifestVersion.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1
1.0.0.0
1
13 changes: 13 additions & 0 deletions Manifest/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version='1.0' encoding='utf-8'?>
<Settings Version='1'>
<Namespace Name='Extensions'>
<Setting Name='ExtensionRepository' Type='VT_BSTR' Value='Implicit'></Setting>
<Namespace Name='ExtensionRepositories'>
<Namespace Name='overgallery'>
<Setting Name='Id' Type='VT_BSTR' Value='458940FE-5649-40DD-AD18-6AC36215BD86'></Setting>
<Setting Name='LocalCacheRootFolder' Type='VT_BSTR' Value='C:\work\Bugalua\Manifest'></Setting>
<Setting Name='IsEnabled' Type='VT_BOOL' Value='true'></Setting>
</Namespace>
</Namespace>
</Namespace>
</Settings>
194 changes: 194 additions & 0 deletions bugalua/bugalua.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
'use strict';

const console = { log: (...args) => host.diagnostics.debugLog(...args, '\n') };

function getLuaState(luaAddr) {
// #region General Types
const ptrsize = host.currentSession.Attributes.Machine.PointerSize;
const voidType = { size: 0, name: 'void', from(addr) { return addr; } };

function int(size, name, signed = false) {
return {
size,
name,
from(addr) { return parseInt(host.memory.readMemoryValues(addr, 1, size, signed)[0]); },
};
}
const [uint8, uint32] = [int(1, 'uint8'), int(4, 'uint32')];
const sizeT = int(ptrsize, 'size_t');

function ptr(type) {
return {
size: ptrsize,
name: `${type.name}*`,
from(addr) {
return {
addr: sizeT.from(addr),
type: type.name,
get value() { return type.from(sizeT.from(addr)); },
toString() { return `[${type.name}* at 0x${addr.toString(16)}]`; },
};
},
};
}
function ptr32(type) {
return {
size: 4,
name: `${type.name}*`,
from(addr) {
return {
addr: uint32.from(addr),
type: type.name,
get value() { return type.from(uint32.from(addr)); },
toString() { return `[${type.name}* at 0x${addr.toString(16)}]`; },
};
},
};
}

function array(type, length) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-unused-vars: 'array' is defined but never used. Allowed unused vars must match /^exports$/u. (eslint)

class Array {
constructor(addr) {
Object.defineProperties(this, {
length: { value: length, writable: false },
[Symbol.iterator]: {
value: () => {
let index = 0;

return {
next: () => ({
done: index >= this.length,
value: type.from(addr + (index++) * type.size),
}),
};
},
},
});
}
}
return { size: length * type.size, name: (`${type.name}[${length}]`), from(addr) { return new Array(addr); } };
}

function struct(name, fieldsArr) {
let offset = 0;
const fields = [];
fieldsArr.forEach(([type, fieldName]) => {
fields.push({ type, fieldName, offset });
offset += type.size;
});
class Struct {
constructor(addr) {
fields.forEach((field) => {
Object.defineProperty(this, field.fieldName, {
get() {
return field.type.from(addr + field.offset);
},
});
});
this.toString = () => `[struct ${name} at 0x${addr.toString(16)}]`;
}
}
return { size: offset, name, from(addr) { return new Struct(addr); } };
}

function defer(fn, name) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-unused-vars: 'defer' is defined but never used. Allowed unused vars must match /^exports$/u. (eslint)

return { get size() { return fn().size; }, name, get from() { return fn().from; } };
}
// #endregion General Types

// #region LuaJIT 2.0.5 Types
const MSize = uint32;
const MRef = ptr32;
const GCRef = ptr32;

const luaJit205GCState = struct('GC_State', [
[MSize, 'total'],
[MSize, 'threshold'],
[uint8, 'currentwhite'],
[uint8, 'state'],
[uint8, 'nocdatafin'],
[uint8, 'unused2'],
[MSize, 'sweepstr'],
[GCRef(voidType), 'root'],
[MRef(voidType), 'sweep'],
[GCRef(voidType), 'gray'],
[GCRef(voidType), 'grayagain'],
[GCRef(voidType), 'weak'],
[GCRef(voidType), 'mmudata'],
[MSize, 'stepmul'],
[MSize, 'debt'],
[MSize, 'estimate'],
[MSize, 'pause'],
]);

const luaJit205GlobalState = struct('global_State', [
[ptr(GCRef(voidType)), 'strhash'],
[MSize, 'strmask'],
[MSize, 'strnum'],
[ptr(voidType), 'allocf'],
[ptr(voidType), 'allocd'],
[luaJit205GCState, 'gc'],
/* Incomplete */
]);

const luaJit205LuaState = struct('lua_State', [
[GCRef(voidType), 'nextgc'],
[uint8, 'marked'],
[uint8, 'gct'],
[uint8, 'dummy_ffid'],
[uint8, 'status'],
[MRef(luaJit205GlobalState), 'glref'],
/* Incomplete */
]);
// #endregion LuaJIT 2.0.5 Types

// #region Frontend
class SizeBytes {
constructor(bytes) {
this.bytes = bytes;
}

toString() {
if (this.bytes <= 512) {
return `${this.bytes.toLocaleString()} B`;
}

const unitsArr = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
let number = this.bytes / 1024;
let units = 0;
while (number > 512) {
number /= 1024;
units += 1;
}
return `${number.toFixed(2)} ${unitsArr[units]} (${this.bytes.toLocaleString()} B)`;
}
}

class LuaState {
constructor(addr) {
this.L = luaJit205LuaState.from(addr);
}

get address() {
return this.L.addr;
}

get MemoryUsage() {
return new SizeBytes(this.L.glref.value.gc.total);
}
}
// #endregion Frontend

return new LuaState(luaAddr);
}

function initializeScript() {
return [
new host.functionAlias((addr) => getLuaState(addr), 'lua'),
];
}

const exports = [
console,
initializeScript,
];
22 changes: 22 additions & 0 deletions bugalua/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "bugalua",
"version": "0.0.1",
"main": "bugalua.js",
"devDependencies": {
"eslint": "*",
"eslint-config-airbnb": "*"
},
"eslintConfig": {
"extends": [ "airbnb" ],
"rules": {
"strict": "off",
"linebreak-style": "off",
"max-classes-per-file": "off",
"no-unused-vars": ["error", { "varsIgnorePattern": "^exports$" }],
"new-cap": "off",
"no-plusplus": "off",
"radix": "off"
},
"globals": { "host": "readonly" }
}
}
21 changes: 21 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[flake8]
max-line-length = 160

[mypy]
namespace_packages = True
strict = True
show_error_codes = True
show_column_numbers = True

[mypy-cffi,minidump.*]
ignore_missing_imports = True

[tool:pytest]
log_cli = 1
log_cli_level = DEBUG
filterwarnings = error

[pylint.config]
max-line-length = 160
output-format = json
disable = missing-module-docstring,missing-class-docstring,missing-function-docstring,broad-except
Loading