Arrowhead

Straightforward native interfacing from Kotlin

APACHE-2.0 License

Stars
14

Arrowhead

Straightforward native interfacing from Kotlin

Gradle

compile group: 'org.jire.arrowhead', name: 'arrowhead', version: '1.3.3'

Maven

<dependency>
  <groupId>org.jire.arrowhead</groupId>
  <artifactId>arrowhead</artifactId>
  <version>1.3.3</version>
</dependency>

Sources

Sources are native references that can be read from and written to through Arrowhead.

Process and Module are the two sources available.

Acquiring a process

You can acquire a process using a name (executable file name):

val process = processByName("process.exe")!!

You can also acquire by process ID (PID):

val process123 = processByID(123)!!

Acquiring a module

You can use .modules off a process for a map of the module name to the Module.

val module = process.modules["module.dll"]!!

Reading from a source

You can use the implicit data type to read from an address:

val someByte: Byte = process[0x123]
val someInt: Int = process[0x123]
val someFloat: Float = process[0x123]
val someBoolean: Boolean = process[0x123]

The implicit type also works when passing arguments or using if expressions.

if (process[0x321]) // Boolean type inferred
    Math.sin(process[0x555]) // Double type inferred

Sometimes it's easier or necessary to use explicit types, and we have you covered:

val someByte = process.byte(0x123)
val someInt = process.int(0x123)
val someFloat = process.float(0x123)
val someBoolean = process.boolean(0x123)

Writing to a source

Writing to a source is just as easy as reading.

You can use "implicit" writing with the set operator.

something[0x123] = 1.toByte()
something[0x123] = 1
something[0x123] = 1F
something[0x123] = true

There are no "explicit" writes, as the "implicit" writes are simply method overloads.

Dealing with structs

Defining structures is the same as in JNA, except you should extend Struct (of org.jire.arrowhead) instead of JNA's Structure (of com.sun.jna) to take advantage of the reuse ("caching") system and other enhancements like automatic field order.

For JNA and Arrowhead to detect fields correctly, make sure to annotate them with @JvmField.

The easiest way to get a struct is by referring to its class type and using the get extension function.

val struct = MyStruct::class.get()

If you have a constructor for your struct type, you can use the get operator to pass the arguments in:

val struct = MyStruct::class["abc", 1, 2, 3]

To read into a struct you can use its read function, which takes the address to read and the source to read from:

struct.read(address = 0x123, source = something)

To write the struct to a source you can use its write function, which is similar to reading:

struct.write(address = 0x123, source = something)

After you're done using a struct you should release it back into the caching pool:

struct.release()
Package Rankings
Top 39.47% on Repo1.maven.org
Badges
Extracted from project README
Build Status Dependency Status License