@@ -9,91 +9,104 @@ namespace ReClassNET.AddressParser
99{
1010 public class DynamicCompiler : IExecuter
1111 {
12- public IntPtr Execute ( IOperation operation , RemoteProcess process )
12+ public IntPtr Execute ( IExpression operation , RemoteProcess process )
1313 {
1414 Contract . Requires ( operation != null ) ;
1515 Contract . Requires ( process != null ) ;
1616
1717 return CompileAddressFormula ( operation ) ( process ) ;
1818 }
1919
20- public Func < RemoteProcess , IntPtr > CompileAddressFormula ( IOperation operation )
20+ public static Func < RemoteProcess , IntPtr > CompileAddressFormula ( IExpression expression )
2121 {
22- Contract . Requires ( operation != null ) ;
22+ Contract . Requires ( expression != null ) ;
2323
2424 var processParameter = Expression . Parameter ( typeof ( RemoteProcess ) ) ;
2525
2626 return Expression . Lambda < Func < RemoteProcess , IntPtr > > (
27- GenerateMethodBody ( operation , processParameter ) ,
27+ GenerateMethodBody ( expression , processParameter ) ,
2828 processParameter
2929 ) . Compile ( ) ;
3030 }
3131
32- private Expression GenerateMethodBody ( IOperation operation , ParameterExpression processParameter )
32+ private static Expression GenerateMethodBody ( IExpression operation , ParameterExpression processParameter )
3333 {
3434 Contract . Requires ( operation != null ) ;
3535 Contract . Requires ( processParameter != null ) ;
3636
3737 switch ( operation )
3838 {
39- case AdditionOperation additionOperation :
40- {
41- var argument1 = GenerateMethodBody ( additionOperation . Argument1 , processParameter ) ;
42- var argument2 = GenerateMethodBody ( additionOperation . Argument2 , processParameter ) ;
43-
44- return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Add ) ) , argument1 , argument2 ) ;
45- }
46- case SubtractionOperation subtractionOperation :
47- {
48- var argument1 = GenerateMethodBody ( subtractionOperation . Argument1 , processParameter ) ;
49- var argument2 = GenerateMethodBody ( subtractionOperation . Argument2 , processParameter ) ;
50-
51- return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Sub ) ) , argument1 , argument2 ) ;
52- }
53- case MultiplicationOperation multiplicationOperation :
54- {
55- var argument1 = GenerateMethodBody ( multiplicationOperation . Argument1 , processParameter ) ;
56- var argument2 = GenerateMethodBody ( multiplicationOperation . Argument2 , processParameter ) ;
57-
58- return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Mul ) ) , argument1 , argument2 ) ;
59- }
60- case DivisionOperation divisionOperation :
61- {
62- var argument1 = GenerateMethodBody ( divisionOperation . Dividend , processParameter ) ;
63- var argument2 = GenerateMethodBody ( divisionOperation . Divisor , processParameter ) ;
64-
65- return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Div ) ) , argument1 , argument2 ) ;
66- }
67- case ModuleOffsetOperation moduleOffsetOperation :
68- {
69- var getModuleByNameFunc = typeof ( RemoteProcess ) . GetRuntimeMethod ( nameof ( RemoteProcess . GetModuleByName ) , new [ ] { typeof ( string ) } ) ;
70- var moduleNameConstant = Expression . Constant ( moduleOffsetOperation . Name ) ;
71-
72- var moduleVariable = Expression . Variable ( typeof ( Memory . Module ) ) ;
73- var assignExpression = Expression . Assign ( moduleVariable , Expression . Call ( processParameter , getModuleByNameFunc , moduleNameConstant ) ) ;
74-
75- return Expression . Block (
76- new [ ] { moduleVariable } ,
77- assignExpression ,
78- Expression . Condition (
79- Expression . Equal ( moduleVariable , Expression . Constant ( null ) ) ,
80- Expression . Constant ( IntPtr . Zero ) ,
81- Expression . MakeMemberAccess ( moduleVariable , typeof ( Memory . Module ) . GetProperty ( nameof ( Memory . Module . Start ) ) )
82- )
83- ) ;
84- }
85- case OffsetOperation offsetOperation :
86- {
87- return Expression . Constant ( offsetOperation . Value ) ;
88- }
89- case ReadPointerOperation readPointerOperation :
90- {
91- var argument = GenerateMethodBody ( readPointerOperation . Argument , processParameter ) ;
92-
93- var readRemoteIntPtrFunc = typeof ( RemoteProcess ) . GetRuntimeMethod ( nameof ( RemoteProcess . ReadRemoteIntPtr ) , new [ ] { typeof ( IntPtr ) } ) ;
94-
95- return Expression . Call ( processParameter , readRemoteIntPtrFunc , argument ) ;
96- }
39+ case AddExpression addExpression :
40+ {
41+ var argument1 = GenerateMethodBody ( addExpression . Lhs , processParameter ) ;
42+ var argument2 = GenerateMethodBody ( addExpression . Rhs , processParameter ) ;
43+
44+ return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Add ) ) , argument1 , argument2 ) ;
45+ }
46+ case SubtractExpression subtractExpression :
47+ {
48+ var argument1 = GenerateMethodBody ( subtractExpression . Lhs , processParameter ) ;
49+ var argument2 = GenerateMethodBody ( subtractExpression . Rhs , processParameter ) ;
50+
51+ return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Sub ) ) , argument1 , argument2 ) ;
52+ }
53+ case MultiplyExpression multiplyExpression :
54+ {
55+ var argument1 = GenerateMethodBody ( multiplyExpression . Lhs , processParameter ) ;
56+ var argument2 = GenerateMethodBody ( multiplyExpression . Rhs , processParameter ) ;
57+
58+ return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Mul ) ) , argument1 , argument2 ) ;
59+ }
60+ case DivideExpression divideExpression :
61+ {
62+ var argument1 = GenerateMethodBody ( divideExpression . Lhs , processParameter ) ;
63+ var argument2 = GenerateMethodBody ( divideExpression . Rhs , processParameter ) ;
64+
65+ return Expression . Call ( null , GetIntPtrExtension ( nameof ( IntPtrExtension . Div ) ) , argument1 , argument2 ) ;
66+ }
67+ case ModuleExpression moduleExpression :
68+ {
69+ var getModuleByNameFunc = typeof ( RemoteProcess ) . GetRuntimeMethod ( nameof ( RemoteProcess . GetModuleByName ) , new [ ] { typeof ( string ) } ) ;
70+ var moduleNameConstant = Expression . Constant ( moduleExpression . Name ) ;
71+
72+ var moduleVariable = Expression . Variable ( typeof ( Memory . Module ) ) ;
73+ var assignExpression = Expression . Assign ( moduleVariable , Expression . Call ( processParameter , getModuleByNameFunc , moduleNameConstant ) ) ;
74+
75+ return Expression . Block (
76+ new [ ] { moduleVariable } ,
77+ assignExpression ,
78+ Expression . Condition (
79+ Expression . Equal ( moduleVariable , Expression . Constant ( null ) ) ,
80+ Expression . Constant ( IntPtr . Zero ) ,
81+ Expression . MakeMemberAccess ( moduleVariable , typeof ( Memory . Module ) . GetProperty ( nameof ( Memory . Module . Start ) ) )
82+ )
83+ ) ;
84+ }
85+ case ConstantExpression constantExpression :
86+ {
87+ #if RECLASSNET64
88+ // long -> IntPtr
89+ return Expression . Convert ( Expression . Constant ( nodeNumber . Value ) , typeof ( IntPtr ) ) ;
90+ #else
91+ // long -> int -> IntPtr
92+ return Expression . Convert ( Expression . Convert ( Expression . Constant ( constantExpression . Value ) , typeof ( int ) ) , typeof ( IntPtr ) ) ;
93+ #endif
94+ }
95+ case ReadMemoryExpression readMemoryExpression :
96+ {
97+ var argument = GenerateMethodBody ( readMemoryExpression . Expression , processParameter ) ;
98+
99+ var functionName = readMemoryExpression . ByteCount == 4 ? nameof ( RemoteProcess . ReadRemoteInt32 ) : nameof ( RemoteProcess . ReadRemoteInt64 ) ;
100+ var readRemoteIntFn = typeof ( RemoteProcess ) . GetRuntimeMethod ( functionName , new [ ] { typeof ( IntPtr ) } ) ;
101+
102+ var callExpression = Expression . Call ( processParameter , readRemoteIntFn , argument ) ;
103+
104+ #if RECLASSNET64
105+ return Expression . Convert ( callExpression , typeof ( IntPtr ) ) ;
106+ #else
107+ return Expression . Convert ( Expression . Convert ( callExpression , typeof ( int ) ) , typeof ( IntPtr ) ) ;
108+ #endif
109+ }
97110 }
98111
99112 throw new ArgumentException ( $ "Unsupported operation '{ operation . GetType ( ) . FullName } '.") ;
0 commit comments