1

I work on cheat for a single player game. I like function composition, immutability and a code without boilerplate so that's why I decided to write the cheat in F#. I finished something which works fine. I know that the code is far from perfect, but today I started my journey with F#.

I wonder if there is a way to somehow remove side effects from my code. Could you give me some hint how this can be achieved?

Thanks,

Rafal

open System;
open System.Diagnostics;
open System.Runtime.InteropServices;
open System.Text;
open System.ComponentModel;

let flip f x y = f y x
let curry f a b = f (a,b)
let uncurry f (a,b) = f a b
type MemoryOperation  = int ->  int -> int  -> byte[]
//(f:int * int * byte[] * int * byref<int> -> bool)

[<DllImport("kernel32.dll")>]
extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId)

[<DllImport("kernel32.dll")>]
extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, int& lpNumberOfBytesWritten)

//let WriteMemory hProcess lpBaseAddress dwSize =
//    let mutable buffer = Array.init dwSize byte
//    let mutable lpNumberOfBytesWritten = 0
//    WriteProcessMemory(hProcess, lpBaseAddress, buffer, dwSize, &lpNumberOfBytesWritten) |> ignore
//    buffer

[<DllImport("kernel32.dll")>]
extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, int& lpNumberOfBytesRead)

let ReadMemory hProcess lpBaseAddress dwSize =
    let mutable buffer = Array.init dwSize byte
    let mutable lpNumberOfBytesRidden = 0
    ReadProcessMemory(hProcess, lpBaseAddress, buffer, dwSize, &lpNumberOfBytesRidden) |> ignore
    buffer


let gameProcesses = Array.toList(Process.GetProcessesByName("gameName"))

let openProcess (p: Process) = 
    let PROCESS_WM_READ = 0x0010
    OpenProcess(PROCESS_WM_READ, false, p.Id)


let readMemory<'a>(bitConverter:byte[] -> 'a)(length:int)(memoryOperation: MemoryOperation)(memory:int)(ptr:IntPtr) = 
    (memoryOperation ((int)ptr) memory length) |> bitConverter


let bitConverter func = func 
                        |> curry 
                        |> flip <| 0
                        |> readMemory

let intIO     = bitConverter BitConverter.ToInt32   4
let booleanIO = bitConverter BitConverter.ToBoolean 1
let charIO    = bitConverter BitConverter.ToChar    1

let readInt      = intIO     ReadMemory
let readBoolean  = booleanIO ReadMemory
let readChar     = charIO    ReadMemory

//let writeInt     = intIO     WriteMemory
//let writeBoolean = booleanIO WriteMemory
//let writeChar    = charIO    WriteMemory

let readHp = readInt 0x00A20D58

[<EntryPoint>]
let main argv = 
    while true do
        gameProcesses |> (openProcess |> List.map)
                      |> (readHp |> List.map)
                      |> List.iter(printfn "%d") 
    0 
NieMaszNic
  • 597
  • 4
  • 21
  • the `DllImport`s basically say you will not get a pure thing anyway - if you just started then please forget all the monad stuff for now – Random Dev Nov 24 '15 at 12:53

1 Answers1

0

IMHO you're using the wrong tool for the job.

You want to intentionally introduce "unintentional" side-effect that goes against original authors, while your language intends to help you do the opposite.

I'd say use something more traditional (C?), if you want to hack through other's process memory. Also, check the license of the application you're trying to hack. You probably intend to violate the terms.

Artur Czajka
  • 18,111
  • 2
  • 28
  • 31
  • 1
    Well, the game itself is an open source. I could just edit the source code, but I want to improve my reverse engineering skills. I like also concise form of the functional code so I'll stay with F# and check what can be achieved. – NieMaszNic Nov 24 '15 at 13:34
  • Probably much, since there's CLR underneath (is that the name?), but it won't be F# any longer ;) – Artur Czajka Nov 24 '15 at 17:51
  • I love it when someone gives a thumbs down, but doesn't leave a comment under the answer... (-_-) – Artur Czajka Oct 14 '18 at 20:16