unidecompiler-plugin-dotnet-cli 0.1.1__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/PKG-INFO +2 -2
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/pyproject.toml +2 -2
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli/assembly.py +16 -4
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli/lifter.py +55 -37
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli/simulation.py +6 -1
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli.egg-info/PKG-INFO +2 -2
- unidecompiler_plugin_dotnet_cli-0.1.3/src/unidecompiler_plugin_dotnet_cli.egg-info/requires.txt +2 -0
- unidecompiler_plugin_dotnet_cli-0.1.1/src/unidecompiler_plugin_dotnet_cli.egg-info/requires.txt +0 -2
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/README.md +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/setup.cfg +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli/__init__.py +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli/plugin.py +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli/support.py +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli.egg-info/SOURCES.txt +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli.egg-info/dependency_links.txt +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli.egg-info/entry_points.txt +0 -0
- {unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/src/unidecompiler_plugin_dotnet_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unidecompiler-plugin-dotnet-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: .NET CLI assembly frontend plugin for unidecompiler
|
|
5
5
|
Author-email: Wker <1670133844@qq.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -9,7 +9,7 @@ Project-URL: Repository, https://github.com/Wker666/unidecompiler
|
|
|
9
9
|
Project-URL: Issues, https://github.com/Wker666/unidecompiler/issues
|
|
10
10
|
Requires-Python: >=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: unidecompiler<0.2.0,>=0.1.
|
|
12
|
+
Requires-Dist: unidecompiler<0.2.0,>=0.1.9
|
|
13
13
|
Requires-Dist: dnfile<1,>=0.15
|
|
14
14
|
|
|
15
15
|
# unidecompiler-plugin-dotnet-cli
|
{unidecompiler_plugin_dotnet_cli-0.1.1 → unidecompiler_plugin_dotnet_cli-0.1.3}/pyproject.toml
RENAMED
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unidecompiler-plugin-dotnet-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = ".NET CLI assembly frontend plugin for unidecompiler"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "AGPL-3.0-or-later"
|
|
11
11
|
authors = [{ name = "Wker", email = "1670133844@qq.com" }]
|
|
12
12
|
requires-python = ">=3.11"
|
|
13
|
-
dependencies = ["unidecompiler>=0.1.
|
|
13
|
+
dependencies = ["unidecompiler>=0.1.9,<0.2.0", "dnfile>=0.15,<1"]
|
|
14
14
|
|
|
15
15
|
[project.urls]
|
|
16
16
|
Homepage = "https://github.com/Wker666/unidecompiler"
|
|
@@ -26,6 +26,8 @@ class DotNetInstruction:
|
|
|
26
26
|
arg_count: int | None = None
|
|
27
27
|
returns_void: bool | None = None
|
|
28
28
|
is_static: bool | None = None
|
|
29
|
+
artifact_offset: int | None = None
|
|
30
|
+
size: int | None = None
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
@dataclass(frozen=True)
|
|
@@ -132,7 +134,7 @@ def _method_listing(pe, row_index: int, row) -> DotNetMethodListing:
|
|
|
132
134
|
param_count=_signature_param_count(row.Signature),
|
|
133
135
|
max_stack=None if body is None else body.max_stack,
|
|
134
136
|
code_size=0 if body is None else len(body.code),
|
|
135
|
-
instructions=() if body is None else _decode_il(pe, body.code),
|
|
137
|
+
instructions=() if body is None else _decode_il(pe, body.code, body.artifact_offset),
|
|
136
138
|
)
|
|
137
139
|
|
|
138
140
|
|
|
@@ -140,6 +142,7 @@ def _method_listing(pe, row_index: int, row) -> DotNetMethodListing:
|
|
|
140
142
|
class _MethodBody:
|
|
141
143
|
max_stack: int
|
|
142
144
|
code: bytes
|
|
145
|
+
artifact_offset: int | None
|
|
143
146
|
|
|
144
147
|
|
|
145
148
|
def _read_method_body(pe, rva: int) -> _MethodBody | None:
|
|
@@ -150,7 +153,7 @@ def _read_method_body(pe, rva: int) -> _MethodBody | None:
|
|
|
150
153
|
kind = first & 0x3
|
|
151
154
|
if kind == 0x2:
|
|
152
155
|
code_size = first >> 2
|
|
153
|
-
return _MethodBody(max_stack=8, code=pe.get_data(rva + 1, code_size))
|
|
156
|
+
return _MethodBody(max_stack=8, code=pe.get_data(rva + 1, code_size), artifact_offset=_artifact_offset(pe, rva + 1))
|
|
154
157
|
if kind == 0x3:
|
|
155
158
|
header = pe.get_data(rva, 12)
|
|
156
159
|
if len(header) < 12:
|
|
@@ -159,7 +162,7 @@ def _read_method_body(pe, rva: int) -> _MethodBody | None:
|
|
|
159
162
|
header_size = (_flags_size >> 12) * 4
|
|
160
163
|
if header_size < 12:
|
|
161
164
|
return None
|
|
162
|
-
return _MethodBody(max_stack=max_stack, code=pe.get_data(rva + header_size, code_size))
|
|
165
|
+
return _MethodBody(max_stack=max_stack, code=pe.get_data(rva + header_size, code_size), artifact_offset=_artifact_offset(pe, rva + header_size))
|
|
163
166
|
return None
|
|
164
167
|
|
|
165
168
|
|
|
@@ -428,7 +431,14 @@ _TWO_BYTE_OPCODES = {
|
|
|
428
431
|
}
|
|
429
432
|
|
|
430
433
|
|
|
431
|
-
def
|
|
434
|
+
def _artifact_offset(pe, rva: int) -> int | None:
|
|
435
|
+
try:
|
|
436
|
+
return int(pe.get_offset_from_rva(rva))
|
|
437
|
+
except Exception:
|
|
438
|
+
return None
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def _decode_il(pe, code: bytes, artifact_offset: int | None = None) -> tuple[DotNetInstruction, ...]:
|
|
432
442
|
instructions: list[DotNetInstruction] = []
|
|
433
443
|
offset = 0
|
|
434
444
|
while offset < len(code):
|
|
@@ -454,6 +464,8 @@ def _decode_il(pe, code: bytes) -> tuple[DotNetInstruction, ...]:
|
|
|
454
464
|
arg_count=operand.arg_count,
|
|
455
465
|
returns_void=operand.returns_void,
|
|
456
466
|
is_static=operand.is_static,
|
|
467
|
+
artifact_offset=None if artifact_offset is None else artifact_offset + start,
|
|
468
|
+
size=offset - start,
|
|
457
469
|
)
|
|
458
470
|
)
|
|
459
471
|
return tuple(instructions)
|
|
@@ -6,6 +6,7 @@ from unidecompiler.core.effects import (
|
|
|
6
6
|
BuildCall,
|
|
7
7
|
CallTopAs,
|
|
8
8
|
DuplicateTop,
|
|
9
|
+
Emit,
|
|
9
10
|
InvokeMember,
|
|
10
11
|
LoadIndirect,
|
|
11
12
|
LoadAttr,
|
|
@@ -15,6 +16,7 @@ from unidecompiler.core.effects import (
|
|
|
15
16
|
Pop,
|
|
16
17
|
Push,
|
|
17
18
|
RaiseTop,
|
|
19
|
+
ReraiseTop,
|
|
18
20
|
ReturnTop,
|
|
19
21
|
StoreAttr,
|
|
20
22
|
StoreIndirect,
|
|
@@ -23,13 +25,14 @@ from unidecompiler.core.effects import (
|
|
|
23
25
|
StoreStaticMember,
|
|
24
26
|
UnknownOpcode,
|
|
25
27
|
)
|
|
26
|
-
from unidecompiler.core.ir import BinaryOp, Const, Expr, Global, IndirectRef, SourceRef, Var
|
|
28
|
+
from unidecompiler.core.ir import BinaryOp, Const, Expr, Global, IndirectRef, SourceRef, Unsupported, Var
|
|
27
29
|
from unidecompiler.core.vm_bytecode import VMBytecodeStep
|
|
28
30
|
from unidecompiler.core.vm_effect_table import VMEffectRule, VMEffectTable
|
|
29
31
|
from unidecompiler.core.vm_function import VMFunctionSpec, lift_steps, lift_vm_step_function, recover_vm_function
|
|
30
32
|
from unidecompiler.core.vm_hints import VMHint
|
|
31
33
|
from unidecompiler.core.vm_module import assemble_vm_module
|
|
32
34
|
from unidecompiler.core.vm_operands import VMDecodedInstruction, VMOperand
|
|
35
|
+
from unidecompiler.provenance import ByteRange
|
|
33
36
|
from unidecompiler.core.vm_region import (
|
|
34
37
|
VMLinearState,
|
|
35
38
|
VMRegionOpcodeClasses,
|
|
@@ -151,38 +154,7 @@ IGNORED_OPS = {
|
|
|
151
154
|
"volatile.",
|
|
152
155
|
"unaligned.",
|
|
153
156
|
"prefix",
|
|
154
|
-
"castclass",
|
|
155
|
-
"box",
|
|
156
|
-
"unbox",
|
|
157
|
-
"unbox.any",
|
|
158
|
-
"conv.i",
|
|
159
|
-
"conv.i1",
|
|
160
|
-
"conv.i2",
|
|
161
|
-
"conv.i4",
|
|
162
|
-
"conv.i8",
|
|
163
|
-
"conv.u",
|
|
164
|
-
"conv.u1",
|
|
165
|
-
"conv.u2",
|
|
166
|
-
"conv.u4",
|
|
167
|
-
"conv.u8",
|
|
168
|
-
"conv.r4",
|
|
169
|
-
"conv.r8",
|
|
170
|
-
"conv.r.un",
|
|
171
|
-
"conv.ovf.i",
|
|
172
|
-
"conv.ovf.i.un",
|
|
173
|
-
"conv.ovf.i1.un",
|
|
174
|
-
"conv.ovf.i2.un",
|
|
175
|
-
"conv.ovf.i4.un",
|
|
176
|
-
"conv.ovf.i8.un",
|
|
177
|
-
"conv.ovf.u",
|
|
178
|
-
"conv.ovf.u.un",
|
|
179
|
-
"conv.ovf.u1.un",
|
|
180
|
-
"conv.ovf.u2.un",
|
|
181
|
-
"conv.ovf.u4.un",
|
|
182
|
-
"conv.ovf.u8.un",
|
|
183
157
|
"endfinally",
|
|
184
|
-
"endfilter",
|
|
185
|
-
"rethrow",
|
|
186
158
|
*CONTROL_OPS,
|
|
187
159
|
}
|
|
188
160
|
|
|
@@ -249,6 +221,13 @@ def _dotnet_load_local_effect(method: DotNetMethodListing, instruction: DotNetIn
|
|
|
249
221
|
if index is None:
|
|
250
222
|
return None
|
|
251
223
|
name = _local_name(method, index)
|
|
224
|
+
if instruction.opcode.startswith("ldloca"):
|
|
225
|
+
return (
|
|
226
|
+
Push(
|
|
227
|
+
source=source,
|
|
228
|
+
value=IndirectRef(source=source, target=Var(name=name, source=source)),
|
|
229
|
+
),
|
|
230
|
+
)
|
|
252
231
|
return (LoadLocal(source=source, name=name, fallback=Var(name=name, source=source)),)
|
|
253
232
|
|
|
254
233
|
|
|
@@ -324,6 +303,36 @@ def _dotnet_call(_method: DotNetMethodListing, instruction: DotNetInstruction, s
|
|
|
324
303
|
)
|
|
325
304
|
|
|
326
305
|
|
|
306
|
+
def _dotnet_operation_call(arg_count: int, *, returns: int = 0):
|
|
307
|
+
def factory(
|
|
308
|
+
_method: DotNetMethodListing,
|
|
309
|
+
instruction: DotNetInstruction,
|
|
310
|
+
source: SourceRef,
|
|
311
|
+
) -> tuple:
|
|
312
|
+
suffix = f"<{instruction.operands}>" if instruction.operands else ""
|
|
313
|
+
return (
|
|
314
|
+
BuildCall(
|
|
315
|
+
source=source,
|
|
316
|
+
callee=Global(name=f"{instruction.opcode}{suffix}", source=source),
|
|
317
|
+
arg_count=arg_count,
|
|
318
|
+
returns=returns,
|
|
319
|
+
),
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
return factory
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def _dotnet_unary_operation(_method, instruction, source: SourceRef) -> tuple:
|
|
326
|
+
# Keep the CLI operation name neutral and readable. Operand metadata is
|
|
327
|
+
# already retained on the decoded instruction; embedding the Python tuple
|
|
328
|
+
# representation in the callee name prevents generic intrinsic handling.
|
|
329
|
+
return (CallTopAs(source=source, callee_name=instruction.opcode),)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _dotnet_unsupported_operation(_method, instruction, source: SourceRef) -> tuple:
|
|
333
|
+
return (Emit(source=source, statement=Unsupported(source=source, message="unsupported CLI control operation", detail=instruction.opcode, raw=(_dotnet_raw_instruction_line(instruction),))),)
|
|
334
|
+
|
|
335
|
+
|
|
327
336
|
DOTNET_EFFECT_TABLE = VMEffectTable(
|
|
328
337
|
opcode_attr="opcode",
|
|
329
338
|
ignored=frozenset(IGNORED_OPS),
|
|
@@ -331,6 +340,12 @@ DOTNET_EFFECT_TABLE = VMEffectTable(
|
|
|
331
340
|
**{opcode: _dotnet_binary(opcode, op) for opcode, op in BINARY_OPS.items()},
|
|
332
341
|
**{opcode: _dotnet_compare(opcode, op) for opcode, op in COMPARE_OPS.items()},
|
|
333
342
|
"ldnull": lambda _method, _instruction, source: (Push(source=source, value=Const(value=None, source=source)),),
|
|
343
|
+
**{opcode: _dotnet_unary_operation for opcode in {
|
|
344
|
+
"castclass", "box", "unbox", "unbox.any", "conv.i", "conv.i1", "conv.i2", "conv.i4", "conv.i8",
|
|
345
|
+
"conv.u", "conv.u1", "conv.u2", "conv.u4", "conv.u8", "conv.r4", "conv.r8", "conv.r.un",
|
|
346
|
+
"conv.ovf.i", "conv.ovf.i.un", "conv.ovf.i1.un", "conv.ovf.i2.un", "conv.ovf.i4.un", "conv.ovf.i8.un",
|
|
347
|
+
"conv.ovf.u", "conv.ovf.u.un", "conv.ovf.u1.un", "conv.ovf.u2.un", "conv.ovf.u4.un", "conv.ovf.u8.un",
|
|
348
|
+
}},
|
|
334
349
|
"dup": lambda _method, instruction, source: (DuplicateTop(source=source, materialized_name=f"local_stack_{instruction.offset}"),),
|
|
335
350
|
"pop": lambda _method, _instruction, source: (Pop(source=source, count=1, emit_calls=True),),
|
|
336
351
|
"neg": lambda _method, _instruction, source: (CallTopAs(source=source, callee_name="neg"),),
|
|
@@ -341,12 +356,12 @@ DOTNET_EFFECT_TABLE = VMEffectTable(
|
|
|
341
356
|
"jmp": _dotnet_call,
|
|
342
357
|
"ldftn": lambda _method, instruction, source: (Push(source=source, value=Global(name=_member_token_name(instruction.operands), source=source)),),
|
|
343
358
|
"ldvirtftn": lambda _method, instruction, source: (Push(source=source, value=Global(name=_member_token_name(instruction.operands), source=source)),),
|
|
344
|
-
"initobj":
|
|
359
|
+
"initobj": _dotnet_operation_call(1),
|
|
345
360
|
"arglist": lambda _method, _instruction, source: (Push(source=source, value=Global(name="arglist", source=source)),),
|
|
346
361
|
"ckfinite": lambda _method, _instruction, source: (CallTopAs(source=source, callee_name="check_finite"),),
|
|
347
|
-
"cpblk":
|
|
348
|
-
"cpobj":
|
|
349
|
-
"initblk":
|
|
362
|
+
"cpblk": _dotnet_operation_call(3),
|
|
363
|
+
"cpobj": _dotnet_operation_call(2),
|
|
364
|
+
"initblk": _dotnet_operation_call(3),
|
|
350
365
|
"localloc": lambda _method, _instruction, source: (BuildCall(source=source, callee=Global(name="localloc", source=source), arg_count=1),),
|
|
351
366
|
"mkrefany": lambda _method, instruction, source: (BuildCall(source=source, callee=Global(name=f"mkrefany<{instruction.operands or 'type'}>", source=source), arg_count=1),),
|
|
352
367
|
"refanytype": lambda _method, _instruction, source: (CallTopAs(source=source, callee_name="refanytype"),),
|
|
@@ -355,7 +370,7 @@ DOTNET_EFFECT_TABLE = VMEffectTable(
|
|
|
355
370
|
"ldstr": lambda _method, instruction, source: (Push(source=source, value=Const(value=instruction.operands, source=source)),),
|
|
356
371
|
"ldtoken": lambda _method, instruction, source: (Push(source=source, value=Global(name=instruction.operands, source=source)),),
|
|
357
372
|
"isinst": lambda _method, instruction, source: (BuildCall(source=source, callee=Global(name="instanceof", source=source), arg_count=1, returns=1),),
|
|
358
|
-
"ldobj":
|
|
373
|
+
"ldobj": _dotnet_operation_call(1, returns=1),
|
|
359
374
|
"ldfld": lambda _method, instruction, source: (LoadAttr(source=source, attr=_member_name(instruction)),),
|
|
360
375
|
"ldflda": lambda _method, instruction, source: (LoadAttr(source=source, attr=_member_name(instruction)),),
|
|
361
376
|
"stfld": lambda _method, instruction, source: (StoreAttr(source=source, attr=_member_name(instruction)),),
|
|
@@ -371,6 +386,8 @@ DOTNET_EFFECT_TABLE = VMEffectTable(
|
|
|
371
386
|
"ldlen": lambda _method, _instruction, source: (LoadAttr(source=source, attr="length"),),
|
|
372
387
|
"newarr": lambda _method, instruction, source: (BuildArrayCall(source=source, kind=instruction.operands or "array"),),
|
|
373
388
|
"throw": lambda _method, _instruction, source: (RaiseTop(source=source),),
|
|
389
|
+
"rethrow": lambda _method, _instruction, source: (ReraiseTop(source=source),),
|
|
390
|
+
"endfilter": _dotnet_unsupported_operation,
|
|
374
391
|
"ret": lambda _method, _instruction, source: (ReturnTop(source=source, empty_is_void=True),),
|
|
375
392
|
},
|
|
376
393
|
rules=(
|
|
@@ -551,6 +568,7 @@ def _dotnet_decoded_instruction(instruction: DotNetInstruction, source: SourceRe
|
|
|
551
568
|
source=source,
|
|
552
569
|
operands=operands,
|
|
553
570
|
raw=_dotnet_raw_instruction_line(instruction),
|
|
571
|
+
artifact_range=(None if instruction.artifact_offset is None or instruction.size is None else ByteRange(instruction.artifact_offset, instruction.size)),
|
|
554
572
|
)
|
|
555
573
|
|
|
556
574
|
|
|
@@ -19,7 +19,12 @@ class DotNetSimulationAdapter:
|
|
|
19
19
|
return ResolvedFunction(matches[0], context=context, identifier=query)
|
|
20
20
|
|
|
21
21
|
def resolve_global(self, name, context):
|
|
22
|
-
from unidecompiler_simulator import NotHandled, ResolvedFunction
|
|
22
|
+
from unidecompiler_simulator import IntrinsicCall, NotHandled, ResolvedFunction
|
|
23
|
+
|
|
24
|
+
# Conversion and unary operation names emitted by the generic lifter
|
|
25
|
+
# are pure value intrinsics, not methods in the lifted module.
|
|
26
|
+
if name.startswith(("conv.", "castclass", "box", "unbox", "neg", "bitnot", "check_finite", "refanytype")):
|
|
27
|
+
return IntrinsicCall(name)
|
|
23
28
|
|
|
24
29
|
if not isinstance(context, dict):
|
|
25
30
|
return NotHandled
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unidecompiler-plugin-dotnet-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: .NET CLI assembly frontend plugin for unidecompiler
|
|
5
5
|
Author-email: Wker <1670133844@qq.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -9,7 +9,7 @@ Project-URL: Repository, https://github.com/Wker666/unidecompiler
|
|
|
9
9
|
Project-URL: Issues, https://github.com/Wker666/unidecompiler/issues
|
|
10
10
|
Requires-Python: >=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: unidecompiler<0.2.0,>=0.1.
|
|
12
|
+
Requires-Dist: unidecompiler<0.2.0,>=0.1.9
|
|
13
13
|
Requires-Dist: dnfile<1,>=0.15
|
|
14
14
|
|
|
15
15
|
# unidecompiler-plugin-dotnet-cli
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|