How To Get lpBaseOfDll Of Module Using GetModuleInformation in Dart By win32 or ffi Library

194 Views Asked by At

I want the to get the lpBaseOfDll Of The Moudle But I Have The Issue In The Following Code I Need Help, pls.
the result of this code 'Pointer: address=0x0' but i tried with python to get the lpBaseOfDll i get this 140716894978048

Pointer<MODULEINFO>? getModuleInformation(String moduleName) {
        final Pointer<ffi.Utf16> lpModuleName;
        Pointer<MODULEINFO> moduleinfo;
        try {
          lpModuleName = moduleName.toNativeUtf16();
          int moduleHandle = GetModuleHandle(lpModuleName);
          moduleinfo = ffi.calloc<MODULEINFO>();
          GetModuleInformation(processDetails!.processHandle, moduleHandle, moduleinfo, moduleinfo.ref.SizeOfImage);
        } catch (error) {
          throw Exception('From Get Module Information:: $error');
        }
    
        // ffi.calloc.free(lpModuleName);
        return moduleinfo;
      }

 final processName = 'NeonAbyss.exe';
  final String moduleName = 'UnityPlayer.dll';
  FlutterMemory flutterMemory = FlutterMemory();
  await flutterMemory.attach(processName: processName);
  Pointer<MODULEINFO>? moduleInfo = flutterMemory.getModuleInformation(moduleName);
  print(moduleInfo!.ref.SizeOfImage); 

that is the full code to understand If You Want To Understand Every Thing

The Error Just In GetModuleInformation

import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart' as ffi;
import 'package:win32/win32.dart';

// class InAddr extends Struct {

//   factory InAddr.allocate(int sAddr) =>
//       calloc<InAddr>().ref
//         ..sAddr = sAddr;

//   @Uint32()
//   external int sAddr;
// }

// sealed class MODULEINFO2 extends Struct {
//   external Pointer<ffi.Utf16> lpBaseOfDll;
//   external Pointer<Uint8> EWntryPoint;
//   @Uint32()
//   external int SizeOfImage;
// }

class ProcessDetails {
  // Porocess Name
  String name;
  // Process Id
  int processID;
  // The type of session that the process is running in.
  // This can be one of several values
  String sessionType;
  //The session ID of the session that the process is running in.
  //This is a number that identifies a user session on the system
  int sessionID;
  // The number of threads currently being used by the process.
  int threadCount;
  // The amount of memory that the process is currently using
  String memoryUsage;

  int processHandle;

  ProcessDetails(
      {required this.name,
      required this.processID,
      required this.sessionType,
      required this.sessionID,
      required this.threadCount,
      required this.memoryUsage,
      this.processHandle = -1});
}

// Flutter Memory For Access To The Running Process
class FlutterMemory {
  ProcessDetails? processDetails;

  Future<void> attach({required String processName}) async {
    try {
      processDetails = await getProcessID(processName);
    } catch (error) {
      print('From Get Process ID :: $error');
    }

    if (processDetails != null) {
      final processHandle = OpenProcess(
          PROCESS_VM_READ |
              PROCESS_VM_WRITE |
              PROCESS_VM_OPERATION |
              PROCESS_CREATE_THREAD |
              PROCESS_CREATE_PROCESS |
              PROCESS_DUP_HANDLE, // desired access flags
          FALSE, // don't inherit handle
          processDetails!.processID);
      processDetails!.processHandle = processHandle;
    }
  }

  Future<ProcessDetails?> getProcessID(String processName) async {
    final processes = await Process.run('tasklist', ['/fo', 'csv', '/nh']);
    if (processes.exitCode == 0) {
      List<String> output = processes.stdout.toString().replaceAll('"', '').split(RegExp(r'\n|\r\n?'));
      for (int index = 0; index < output.length; index++) {
        String task = output[index];
        if (task.contains(processName)) {
          List<dynamic> splitedTask = task.split(',');
          return ProcessDetails(
              memoryUsage: splitedTask.last,
              name: splitedTask[0],
              processID: int.parse(splitedTask[1]),
              sessionID: splitedTask.length - 1 == 4 ? int.parse(splitedTask[3]) : int.parse(splitedTask[4]),
              sessionType: splitedTask[2],
              threadCount: splitedTask.length - 1 == 4 ? -1 : int.parse(splitedTask[4]));
        }
      }
      throw Exception('The Process is Not Running ( $processName )');
    }
  }

  int? getPointerAddress(int base, List<int> offsets) {
    try {
      int addr = readInt16(address: base)!;
      for (int offset in offsets) {
        if (offset != offsets.last) {
          addr = readInt16(address: base + offset)!;
        }
      }
      addr = addr + offsets.last;
      return addr;
    } catch (error) {
      print('From Get Pointer Address:: $error');
      return -1;
    }
  }

  Pointer<MODULEINFO>? getModuleInformation(String moduleName) {
    final Pointer<ffi.Utf16> lpModuleName;
    Pointer<MODULEINFO> moduleinfo;
    try {
      lpModuleName = moduleName.toNativeUtf16();
      int moduleHandle = GetModuleHandle(lpModuleName);
      moduleinfo = ffi.calloc<MODULEINFO>();
      GetModuleInformation(processDetails!.processHandle, moduleHandle, moduleinfo, 1000000);
    } catch (error) {
      throw Exception('From Get Module Information:: $error');
    }

    // ffi.calloc.free(lpModuleName);
    return moduleinfo;
  }

  // Write Float Value Inside Address In Memory
  bool writeFloat({required int address, required double data}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Float>();
    buffer.value = data;
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = WriteProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Float>(), bytesWritten);
        return isDone == 1 ? true : false;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  bool writeInt64({required int address, required int data}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Int64>();
    buffer.value = data;
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = WriteProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Int64>(), bytesWritten);
        return isDone == 1 ? true : false;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  bool writeInt32({required int address, required int data}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Int32>();
    buffer.value = data;
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = WriteProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Int32>(), bytesWritten);
        return isDone == 1 ? true : false;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  bool writeInt16({required int address, required int data}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Int16>();
    buffer.value = data;
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = WriteProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Int16>(), bytesWritten);
        return isDone == 1 ? true : false;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  double? readFloat({required int address}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Float>();
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = ReadProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Float>(), bytesWritten);
        if (isDone == 1) return buffer.value;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  int? readInt16({required int address}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Int16>();
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = ReadProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Int16>(), bytesWritten);
        if (isDone == 1) return buffer.value;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  int? readInt32({required int address}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Int32>();
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = ReadProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Int32>(), bytesWritten);
        if (isDone == 1) return buffer.value;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }

  int? readInt64({required int address}) {
    var memoryAddress = Pointer.fromAddress(address);
    final buffer = ffi.calloc<Int64>();
    final bytesWritten = ffi.calloc<IntPtr>();
    // Try To Write in Memory
    if (processDetails!.processHandle != -1) {
      try {
        int isDone = ReadProcessMemory(processDetails!.processHandle, memoryAddress, buffer, sizeOf<Int64>(), bytesWritten);
        if (isDone == 1) return buffer.value;
      } catch (error) {
        rethrow;
      }
    } else {
      throw Exception('Attach The Process');
    }
  }
}

void main(List<String> args) async {
  final processName = 'NeonAbyss.exe';
  final String moduleName = 'UnityPlayer.dll';
  FlutterMemory flutterMemory = FlutterMemory();
  await flutterMemory.attach(processName: processName);
  Pointer<MODULEINFO>? moduleInfo = flutterMemory.getModuleInformation(moduleName);
  print(moduleInfo!.ref.lpBaseOfDll); // 140716894978048

  // int? address = flutterMemory.getPointerAddress(0x26CB3FA525C, [0xC8, 0x80, 0x28, 0x238, 0x20, 0x78, 0x25C]);
  // bool result = flutterMemory.writeFloat(
  //   address: flutterMemory.getPointerAddress('base' + , offsets, ),
  //    data: 2.375);
  // print(result);
}
1

There are 1 best solutions below

0
Ahmed Jihad On

This code gave me the answer

class Module {
          String name;
          String path;
          Pointer<NativeType>? lpBaseOfDll;
          int SizeOfImage;
          Pointer<NativeType>? EntryPoint;
          Module({this.name = '', this.path = '', this.lpBaseOfDll, this.SizeOfImage = -1, this.EntryPoint});
        
          @override
          String toString() {
            return 'Module: name: $name, lpBaseOfDll: $lpBaseOfDll, SizeOfImage: $SizeOfImage, EntryPoint: $EntryPoint';
          }
        }
        
        
        Module moduleFromName(String name) {
            for (Module module in _enumProcessModule()) {
              if (module.name == name) {
                return module;
              }
            }
            throw Exception('This Module Not Fount:: $name');
          }
        
          Iterable<Module> _enumProcessModule() sync* {
            final hMods = ffi.calloc<HMODULE>(1024);
            final cbNeeded = ffi.calloc<DWORD>();
            if (EnumProcessModulesEx(processDetails!.processHandle, hMods, sizeOf<HMODULE>() * 1024, cbNeeded, 0x03) == 1) {
              for (var i = 0; i < (cbNeeded.value ~/ sizeOf<HMODULE>()); i++) {
                final hModule = hMods.elementAt(i).value;
                Pointer<MODULEINFO> lpmodinfo = ffi.calloc<MODULEINFO>();
                final szModName = wsalloc(MAX_PATH);
                Module module = Module();
                if (GetModuleFileNameEx(processDetails!.processHandle, hModule, szModName, MAX_PATH) != 0) {
                  module.path = szModName.toDartString();
                  module.name = module.path.split('\\').last;
                }
                if (GetModuleInformation(processDetails!.processHandle, hModule, lpmodinfo, sizeOf<MODULEINFO>() * 1024) != 0) {
                  module.lpBaseOfDll = lpmodinfo.ref.lpBaseOfDll;
                  module.SizeOfImage = lpmodinfo.ref.SizeOfImage;
                  module.EntryPoint = lpmodinfo.ref.EntryPoint;
                }
                yield module;
                free(szModName);
                free(lpmodinfo);
              }
            }
        
            free(hMods);
            free(cbNeeded);
          }