Skip to content

Commit

Permalink
Merge pull request #46 from gen0cide/function-generator
Browse files Browse the repository at this point in the history
Function generator
  • Loading branch information
gen0cide authored Mar 10, 2018
2 parents 29651c2 + 00b6a46 commit a1a6765
Show file tree
Hide file tree
Showing 69 changed files with 4,532 additions and 637 deletions.
107 changes: 107 additions & 0 deletions DEVELOP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Function Development

Below is a tutorial on how to develop a VM function in gscript.

## Location

Functions are defined in `engine/lib_*.go` files. Each "package" has it's own `lib_` file. Please place your methods in the correct folder.

Your function configuration will be placed in `functions.yml` under the corresponding package section.


## Rules / Known Limitations

Functions are defined in `engine/lib_*.go` files. Each "package" has it's own `lib_` file. Please place your methods in the correct folder.

Example:

```
func (e *Engine) WriteFile(path string, fileData []byte, perms int64) (int, error)
^ ^ ^ ^
1 2 3 4
```

1. Method must be defined as a **pointer receiver** to the `Engine` type.
2. Method must begin with a capital, and be camel cased appropriately. Follow Golang naming conventions. Your Golang function name is what your function inside the VM will be named.
3. Properly name your variables - descriptive and unique! Also, do not use any built in Golang reserved keywords or types. Arguments should also be lowercase, but continuing the camelCase convention of Golang.
4. The function must return something. Whatever that something is should be able to be marshaled into JSON. If your function doesn't return something (even a boolean) you're going to have a bad time.

## Tutorial
For this example, I will implement the `WriteFile()` command.


### 1) Write Golang Function
First, implement your function following the guidelines above.


```
func (e *Engine) WriteFile(path string, fileData []byte, perms int64) (int, error) {
err := ioutil.WriteFile(path, fileData, os.FileMode(uint32(perms)))
if err != nil {
e.Logger.WithField("trace", "true").Errorf("Error writing the file: %s", err.Error())
return 0, err
}
return len(fileData), nil
}
```

Since this has to do with files, we will place it in `engine/lib_file.go`.

**IMPORTANT** - HANDLE ALL YOUR ERRORS. If you don't, you'll break gscript. Make them fail gracefully.

### 2) Write Function Config

Now we will open `functions.yml` and copy the following block into the `file package` section.

```
- name: WriteFile
description: Writes data from a byte array to a file with the given permissions.
author: Alex
package: file
args:
- label: path
gotype: string
- label: fileData
gotype: '[]byte'
- label: perms
gotype: int64
returns:
- label: bytesWritten
gotype: int
return: true
- label: fileError
gotype: error
return: true
```

* `name:` - This is the name of your function as you write it in the Golang lib.
* `descripton:` - This is what will be generated in the function documentation. Be accurate.
* `author:` - This is you!
* `package:` - This is the engine package we determined above. (more around this in development)
* `args:` - This is where you will document your function arguments.
* `label:` - variable name as displayed in the function definition.
* `gotype:` - The type in Golang of that argument. Note the VM can be wacky, it tries to do type conversion but sometime it gets it wrong.
* `returns:` - This is where you'll document the return values of your method.
* `label:` - This will be the field assigned to the Javascript return object.
* `gotype:` - This is the Golang type of this argument.
* `return:` - TRUE or FALSE, should this be included in the return object.

To show you what the return will look like in the VM, here's a brief pseudocode example:

```
var ret = WriteFile("/tmp/tater.jpg", Asset("tater.jpg"), 0644);
// ret.bytesWritten = 488204
// ret.fileError = nil
```

### 3) Build gscript

After saving `engine/lib_file.go` and `functions.yml`, now it's time to generate and build!

In the root of the repo is a script called `build_cli.sh`. Run this to build gscript. If you've got type mismatches or problems with anything in steps 1 or 2, you should get errors here.

Note that generation is *part* of the `build_cli.sh` script. You should see it's output!

### 4) Done!

Now you can look at `FUNCTIONS.md` and see your new documentation rendered.
236 changes: 236 additions & 0 deletions FUNCTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# Native Functions



## `Asset(assetName)`

Retrieves a packed asset from the VM embedded file store.

### Argument List

* **assetName** *string*

### Returned Object Fields

* **fileData** *[]byte*
* **err** *error*

---



## `DeobfuscateString(str)`

Basic string deobfuscator function.

### Argument List

* **str** *string*

### Returned Object Fields

* **value** *string*

---



## `ExecuteCommand(baseCmd, cmdArgs)`

Executes system commands.

### Argument List

* **baseCmd** *string*
* **cmdArgs** *[]string*

### Returned Object Fields

* **retObject** *VMExecResponse*

---



## `ForkExecuteCommand(baseCmd, cmdArgs)`

Executes system commands via a forked call.

### Argument List

* **baseCmd** *string*
* **cmdArgs** *[]string*

### Returned Object Fields

* **pid** *int*
* **execError** *error*

---



## `Halt()`

Stop the current VM from continuing execution.

### Argument List


### Returned Object Fields

* **value** *bool*

---



## `MD5(data)`

Perform an MD5() hash on data.

### Argument List

* **data** *[]byte*

### Returned Object Fields

* **value** *string*

---



## `ObfuscateString(str)`

Basic string obfuscator function.

### Argument List

* **str** *string*

### Returned Object Fields

* **value** *string*

---



## `RandomInt(min, max)`

Generates a random number between min and max.

### Argument List

* **min** *int64*
* **max** *int64*

### Returned Object Fields

* **value** *int*

---



## `RandomMixedCaseString(strlen)`

Generates a random mixed case alpha numeric string of a specified length.

### Argument List

* **strlen** *int64*

### Returned Object Fields

* **value** *string*

---



## `RandomString(strlen)`

Generates a random alpha numeric string of a specified length.

### Argument List

* **strlen** *int64*

### Returned Object Fields

* **value** *string*

---



## `StripSpaces(str)`

Strip any unicode characters out of a string.

### Argument List

* **str** *string*

### Returned Object Fields

* **value** *string*

---



## `Timestamp()`

Get the system's current timestamp in epoch format.

### Argument List


### Returned Object Fields

* **value** *int64*

---



## `WriteFile(path, fileData, perms)`

Writes data from a byte array to a file with the given permissions.

### Argument List

* **path** *string*
* **fileData** *[]byte*
* **perms** *int64*

### Returned Object Fields

* **bytesWritten** *int*
* **fileError** *error*

---



## `XorBytes(aByteArray, bByteArray)`

XOR two byte arrays together.

### Argument List

* **aByteArray** *[]byte*
* **bByteArray** *[]byte*

### Returned Object Fields

* **value** *[]byte*

---




Loading

0 comments on commit a1a6765

Please sign in to comment.