read/write another process memory monad in F# - f#

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

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.

Related

F# Equivalent of ++ operator

I'm converting an array to a record type. Something like:
let value = [|"1";"2";"3";"Not a number";"5"|]
type ValueRecord = {
One: int32
Two: int32
Three: int32
Four: string
Five: int32 }
let convertArrayToRecord (x: string array) =
{ One = x.[0] |> Int.Parse
Two = x.[1] |> Int.Parse
Three = x.[2] |> Int.Parse
Four = x.[3]
Five = x.[4] |> Int.Parse }
let recordValue = convertArrayToRecord value
This works, but has the drawback that adding a value to the middle of the array results in manual editing of all index references thereafter like this:
let value = [|"1";"Not a number - 6";"2";"3";"Not a number";"5"|]
type ValueRecord = {
One: int32
Six: string
Two: int32
Three: int32
Four: string
Five: int32 }
let convertArrayToRecord (x: string array) =
{ One = x.[0] |> Int.Parse
Six = x.[1]
Two = x.[2] |> Int.Parse //<--updated index
Three = x.[3] |> Int.Parse //<--updated index
Four = x.[4] //<--updated index
Five = x.[5] |> Int.Parse } //<--updated index
let recordValue = convertArrayToRecord value
Additionally, its easy to accidentally get the indexes wrong.
The solution I came up with is:
let convertArrayToRecord (x: string array) =
let index = ref 0
let getIndex () =
let result = !index
index := result + 1
result
{ One = x.[getIndex ()] |> Int.Parse
Six = x.[getIndex ()]
Two = x.[getIndex ()] |> Int.Parse
Three = x.[getIndex ()] |> Int.Parse
Four = x.[getIndex ()]
Five = x.[getIndex ()] |> Int.Parse }
This works, but I really dislike the ref cell for something which isn't concurrent. Is there a better/cleaner way to accomplish this?
You could use pattern matching.
let convertArrayToRecord = function
| [|one; two; three; four; five|] ->
{
One = int one
Two = int two
Three = int three
Four = four
Five = int five
}
| _ ->
failwith "How do you want to deal with arrays of a different length"
When adding another entry to the array you'd adjust it by editing the first match to [|one; six; two; three; four; five|].
By the way, for a mutable index like the one you're using in your current example, you can avoid ref by using the mutable keyword instead, like so;
let mutable index = -1
let getIndex =
index <- index + 1
index
And if we hide the mutable inside the getIndex function
let getIndex =
let mutable index = -1
fun () ->
index <- index + 1
index
You could let the indexes be handled with pattern matching, and add an active pattern, like this:
let (|PInt32|_|) (s:string) =
let ok, i = Int32.TryParse(s)
if ok then Some(PInt32(s)) else None
let foo() =
match [|"1"; "2"; "Some str"|] with
| [|PInt32(x); PInt32(y); mystr|] ->
printfn "Yup"
| _ -> printfn "Nope"

Call async method in an inner lambda? "This construct may only be used within computation expressions"

I have the following code
let rec consume() : Async<unit> = async {
.....
listA
|> Seq.iter(fun i ->
.....
let listB : seq<...> option =
let c = getListB a b
match c with
| Some d -> Seq.filter(....) |> Some
| None -> None
match listB with .....
....
Now the function getListB is converted to return async<Seq<B>> instead of Seq<B>. So the code was converted to the following. However, the getListB blocked the execution. How to rewrite it nonblocking? Simply convert the line to let! c = getListB a b won't work because the code is in an inner lambda? The error message is "This construct may only be used within computation expressions".
let rec consume() : Async<unit> = async {
.....
listA
|> Seq.iter(fun i ->
.....
let listB : seq<...> option =
let c = getListB a b |> Async.RunSynchronously
match c with
| Some d -> Seq.filter(....) |> Some
| None -> None
I believe the problem you are describing boils down to how to convert an seq<Async> to an Async<seq>. This is described comprehensively in this post by Scott Wlaschin.
This is a poor man's implementation of the concepts described in his post which are far more powerful and generic. The general idea is that we want to delay the creation of the sequence until we have the values promised by the instance of Async<_>
let traverseSequence ( seqAsync : seq<Async<'a>>) =
let promiseOfAnEmptySequence = async { return Seq.empty }
let delayedCalculation (asyncHead : Async<'a>) (asyncTail : Async<seq<'a>>) =
async {
let! calculatedHead = asyncHead
return!
async {
let! calculatedTail = asyncTail
return calculatedHead |> Seq.singleton |> Seq.append(calculatedTail)
}
}
Seq.foldBack delayedCalculation seqAsync promiseOfAnEmptySequence
The answer depends on whether you want to run each element of the sequence sequentially or in parallel.
In both cases, start by using Seq.map instead of Seq.iter, then you can put another async block inside the lambda such that the result of the map is seq<Async<'a>>.
Sequential
For this, you need define some extra functions in an extra Async module.
module Async =
let map f x =
async{
let! x = x
return f x
}
let lift2 f x1 x2 =
async{
let! x1 = x1
let! x2 = x2
return f x1 x2
}
let return' x = async { return x }
let mapM mFunc sequ =
let consF x ys = lift2 (fun h t -> h::t) (mFunc x) ys
Seq.foldBack(consF) sequ (return' [])
|> map (Seq.ofList)
let sequence sequ = mapM id sequ
You might have seen mapM called traverse elsewhere, they are basically just different names for the same concept.
The sequence function is just a special case of mapM where the supplied binding function is just the identity (id) function. It has type seq<Async<'a>> -> Async<seq<'a>>, i.e. it flips the Async from being inside the Seq to being outside.
You then simply pipe the result of your Seq.map to the sequence function, which gives you an async value.
Your example code isn't complete so I made up some example code to use this:
let sleep = Async.Sleep 100
let sleeps = Seq.init 15 (fun _ -> sleep)
let sequencedSleeps = Async.sequence sleeps
Async.RunSynchronously sequencedSleeps
Real: 00:00:01.632, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : seq<unit> =
[null; null; null; null; null; null; null; null; null; null; null; null;
null; null; null]
Parallel
To execute each element of the sequence in parallel, instead of sequentially, you could do:
let pSequence sequ = Async.Parallel sequ |> Async.map (Seq.ofArray)
Example test code:
let pSleeps = pSequence sleeps;;
Async.RunSynchronously pSleeps;;
Real: 00:00:00.104, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : seq<unit> = seq [null; null; null; null; ...]
Note how the execution time depends on the chosen approach.
For the cases where you're getting back a seq<unit> and so want to ignore the result it can be useful to define some extra helper functions, such as:
let sequenceIgnore sequ = sequ |> Async.sequence |> Async.map (ignore)
let pSequenceIgnore sequ = sequ |> pSequence |> Async.map (ignore)
That lets you return a single unit rather than a superfluous sequence of them.

F# computation expression transparent state passing with Bind

I have the following code that try to read a possibly incomplete data (image data, for example) from a network stream using usual MaybeBuilder:
let image = maybe {
let pos = 2 //Initial position skips 2 bytes of packet ID
let! width, pos = readStreamAsInt 2 pos
let! height, pos = readStreamAsInt 2 pos
let! data, pos = readStream (width*height) pos
advanceInStream pos
return {width = width; height = height; pixels = data}
}
So, readStream[asInt] [numBytes] [offset] function returns Some [data] or None if data has not arrived yet in a NetworkStream. advanceInStream function is executed when whole network packet is read.
I wonder if there is some way to write some custom computation expression builder to hide pos passing from its user, since it's always the same - I read some data and position in stream and pass it to the next read function as a last parameter.
P.S. MaybeBuilder used:
type MaybeBuilder() =
member x.Bind(d,f) = Option.bind f d
member x.Return d = Some d
member x.ReturnFrom d = d
member x.Zero() = None
let maybe = new MaybeBuilder()
P.P.S
On second thought it seems I have to make pos mutable, because of possible "for" or "while" loops in reading. Simple let! works fine with pos Bind shadowing, but you can't hold onto immutability if you add reading in a loop, right? The task becomes trivial then.
#bytebuster is making good points of maintainability about custom computation expressions but I still thought I demonstrate how to combine the State and Maybe monad into one.
In "traditional" languages we have good support for composing values such as integers but we run into problems when developing parsers (Producing values from a binary stream is essentially parsing). For parsers we would like to compose simple parser functions into more complex parser functions but here "traditional" languages often lack good support.
In functional languages functions are as ordinary as values and since values can be composed obviously functions can be as well.
First let's define a StreamReader function. A StreamReader takes a StreamPosition (stream + position) and produces an updated StreamPosition and a StreamReaderResult (the read value or a failure).
type StreamReader<'T> =
StreamReader of (StreamPosition -> StreamPosition*StreamReaderResult<'T>)
(This is the most important step.)
We like to be able to compose simple StreamReader functions into more complex ones. A very important property we want to maintain is that the compose operation is "closed" under StreamReader meaning that result of composition is a new StreamReader which in turn can be composed endlessly.
In order to read an image we need to read the width & height, compute the product and read the bytes. Something like this:
let readImage =
reader {
let! width = readInt32
let! height = readInt32
let! bytes = readBytes (width*height)
return width, height, bytes
}
Because of composition being closed readImage is a StreamReader<int*int*byte[]>.
In order to be able to compose StreamReader like above we need to define a computation expression but before we can do that we need to define the operation Return and Bind for StreamReader. It turns out Yield is good to have as well.
module StreamReader =
let Return v : StreamReader<'T> =
StreamReader <| fun sp ->
sp, (Success v)
let Bind (StreamReader t) (fu : 'T -> StreamReader<'U>) : StreamReader<'U> =
StreamReader <| fun sp ->
let tsp, tr = t sp
match tr with
| Success tv ->
let (StreamReader u) = fu tv
u tsp
| Failure tfs -> tsp, Failure tfs
let Yield (ft : unit -> StreamReader<'T>) : StreamReader<'T> =
StreamReader <| fun sp ->
let (StreamReader t) = ft ()
t sp
Return is trivial as the StreamReader should return the given value and don't update the StreamPosition.
Bind is a bit more challenging but describes how to compose two StreamReader functions into a new one. Bind runs the first StreamReader function and checks the result, if it's a failure it returns a failure otherwise it uses the StreamReader result to compute the second StreamReader and runs that on the update stream position.
Yield just creates the StreamReader function and runs it. Yield is used by F# when building computation expressions.
Finally let's create the computation expression builder
type StreamReaderBuilder() =
member x.Return v = StreamReader.Return v
member x.Bind(t,fu) = StreamReader.Bind t fu
member x.Yield(ft) = StreamReader.Yield ft
let reader = StreamReaderBuilder ()
Now we built the basic framework for combining StreamReader functions. In addition we would we need to define the primitive StreamReader functions.
Full example:
open System
open System.IO
// The result of a stream reader operation is either
// Success of value
// Failure of list of failures
type StreamReaderResult<'T> =
| Success of 'T
| Failure of (string*StreamPosition) list
and StreamPosition =
{
Stream : byte[]
Position : int
}
member x.Remaining = max 0 (x.Stream.Length - x.Position)
member x.ReadBytes (size : int) : StreamPosition*StreamReaderResult<byte[]> =
if x.Remaining < size then
x, Failure ["EOS", x]
else
let nsp = StreamPosition.New x.Stream (x.Position + size)
nsp, Success (x.Stream.[x.Position..(x.Position + size - 1)])
member x.Read (converter : byte[]*int -> 'T) : StreamPosition*StreamReaderResult<'T> =
let size = sizeof<'T>
if x.Remaining < size then
x, Failure ["EOS", x]
else
let nsp = StreamPosition.New x.Stream (x.Position + size)
nsp, Success (converter (x.Stream, x.Position))
static member New s p = {Stream = s; Position = p;}
// Defining the StreamReader<'T> function is the most important decision
// In this case a stream reader is a function that takes a StreamPosition
// and produces a (potentially) new StreamPosition and a StreamReadeResult
type StreamReader<'T> = StreamReader of (StreamPosition -> StreamPosition*StreamReaderResult<'T>)
// Defining the StreamReader CE
module StreamReader =
let Return v : StreamReader<'T> =
StreamReader <| fun sp ->
sp, (Success v)
let Bind (StreamReader t) (fu : 'T -> StreamReader<'U>) : StreamReader<'U> =
StreamReader <| fun sp ->
let tsp, tr = t sp
match tr with
| Success tv ->
let (StreamReader u) = fu tv
u tsp
| Failure tfs -> tsp, Failure tfs
let Yield (ft : unit -> StreamReader<'T>) : StreamReader<'T> =
StreamReader <| fun sp ->
let (StreamReader t) = ft ()
t sp
type StreamReaderBuilder() =
member x.Return v = StreamReader.Return v
member x.Bind(t,fu) = StreamReader.Bind t fu
member x.Yield(ft) = StreamReader.Yield ft
let reader = StreamReaderBuilder ()
let read (StreamReader sr) (bytes : byte[]) (pos : int) : StreamReaderResult<'T> =
let sp = StreamPosition.New bytes pos
let _, sr = sr sp
sr
// Defining various stream reader functions
let readValue (converter : byte[]*int -> 'T) : StreamReader<'T> =
StreamReader <| fun sp -> sp.Read converter
let readInt32 = readValue BitConverter.ToInt32
let readInt16 = readValue BitConverter.ToInt16
let readBytes size : StreamReader<byte[]> =
StreamReader <| fun sp ->
sp.ReadBytes size
let readImage =
reader {
let! width = readInt32
let! height = readInt32
let! bytes = readBytes (width*height)
return width, height, bytes
}
[<EntryPoint>]
let main argv =
// Sample byte stream
let bytes = [|2;0;0;0;3;0;0;0;1;2;3;4;5;6|] |> Array.map byte
let result = read readImage bytes 0
printfn "%A" result
0

How to define x++ (where x: int ref) in F#?

I currently use this function
let inc (i : int ref) =
let res = !i
i := res + 1
res
to write things like
let str = input.[inc index]
How define increment operator ++, so that I could write
let str = input.[index++]
You cannot define postfix operators in F# - see 4.4 Operators and Precedence. If you agree to making it prefix instead, then you can define, for example,
let (++) x = incr x; !x
and use it as below:
let y = ref 1
(++) y;;
val y : int ref = {contents = 2;}
UPDATE: as fpessoa pointed out ++ cannot be used as a genuine prefix operator, indeed (see here and there for the rules upon characters and character sequences comprising valid F# prefix operators).
Interestingly, the unary + can be overloaded for the purpose:
let (~+) x = incr x; !x
allowing
let y = ref 1
+y;;
val y : int ref = {contents = 2;}
Nevertheless, it makes sense to mention that the idea of iterating an array like below
let v = [| 1..5 |]
let i = ref -1
v |> Seq.iter (fun _ -> printfn "%d" v.[+i])
for the sake of "readability" looks at least strange in comparison with the idiomatic functional manner
[|1..5|] |> Seq.iter (printfn "%d")
which some initiated already had expressed in comments to the original question.
I was trying to write it as a prefix operator as suggested, but you can't define (++) as a proper prefix operator, i.e., run things like ++y without the () as you could for example for (!+):
let (!+) (i : int ref) = incr i; !i
let v = [| 1..5 |]
let i = ref -1
[1..5] |> Seq.iter (fun _ -> printfn "%d" v.[!+i])
Sorry, but I guess the answer is that actually you can't do even that.

F# compose pattern matched function

I have these types:
type ShouldRetry = ShouldRetry of (RetryCount * LastException -> bool * RetryDelay)
and RetryCount = int
and LastException = exn
and RetryDelay = TimeSpan
type RetryPolicy = RetryPolicy of ShouldRetry
Now I want composability of the retries; something like this:
let serverOverloaded = [| exnRetry<TimeoutException>;
exnRetry<ServerBusyException> |]
|> Array.map (fun fn -> fn (TimeSpan.FromSeconds(4.0)))
let badNetwork = [||] // etc
let compose p1 p2 =
// http://fssnip.net/7h
RetryPolicy(ShouldRetry( (fun (c,e) ->
let RetryPolicy(ShouldRetry(fn)) = p1
let RetryPolicy(ShouldRetry(fn')) = p2
let (cont, delay) = fn c,e
if cont then cont, delay
else
let (cont', delay') = fn' c,e
cont', delay') ))
let finalPolicy = serverOverloaded |> Array.scan compose (RetryPolicies.NoRetry())
But I'm getting compiler errors on fn, delay and fn', saying "The value or constructor 'fn' is not defined".
I can see two problems in your compose function.
When decomposing p1 and p2, the pattern needs to be wrapped in parentheses (otherwise, the compiler interprets the code as a definition of RetryPolicy function, instead of pattern matching):
let (RetryPolicy(ShouldRetry(fn))) = p1
let (RetryPolicy(ShouldRetry(fn'))) = p2
When calling fn' a bit later, you need to pass it the arguments in a tuple (otherwise, the compiler thinks that you're calling fn' with just a single argument c and then building a tuple):
let (cont', delay') = fn' (c,e)
I didn't check (or tried to run) the whole example, so I don't know if the rest of the code does what you want.

Resources