Repository: guitmz/memrun
Branch: master
Commit: 4a5d8ca91eed
Files: 8
Total size: 16.8 KB
Directory structure:
gitextract_cb4r4ys1/
├── .gitattributes
├── LICENSE
├── README.md
├── assembly/
│ ├── README.md
│ ├── memrun.asm
│ ├── struct.inc
│ └── utils.inc
└── memrun.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
assembly/*.inc linguist-language=Assembly
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 Guilherme Thomazi Bonicontro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# memrun
Small tool written in Golang to run ELF (x86_64) binaries from memory with a given process name. Works on Linux where kernel version is >= 3.17 (relies on the `memfd_create` syscall).
# Usage
Build it with `$ go build memrun.go` and execute it. The first argument is the process name (string) you want to see in `ps auxww` output for example. Second argument is the path for the ELF binary you want to run from memory.
```
Usage: memrun process_name elf_binary
```
================================================
FILE: assembly/README.md
================================================
# memrun
Small tool written in Assembly (FASM) to run ELF (x86_64) binaries from memory with a given process name. Works on Linux where kernel version is >= 3.17 (relies on the `memfd_create` syscall).
# Usage
Build it with `$ fasm memrun.asm` and execute it. The first argument is the path for the ELF binary you want to run from memory and the second argument is the process name (string) you want to see in `ps auxww` output for example.
```
Usage: memrun <path_to_elf_file> <process_name>
```
================================================
FILE: assembly/memrun.asm
================================================
format ELF64 executable 3
include "struct.inc"
include "utils.inc"
segment readable executable
entry start
start:
;-----------------------------------------------------------------------------
; parsing command line arguments
;-----------------------------------------------------------------------------
pop rcx ; arg count
cmp rcx, 3 ; needs to be at least two for the self program arg0 and target arg1
jne usage ; exit 1 if not
add rsp, 8 ; skips arg0
pop rsi ; gets arg1
mov rdi, sourcePath
push rsi ; save rsi
push rdi
call strToVar
pop rsi ; restore rsi
pop rdi
mov rdi, targetProcessName
pop rsi ; gets arg2
push rdi
call strToVar
;-----------------------------------------------------------------------------
; opening source file for reading
;-----------------------------------------------------------------------------
mov rdi, sourcePath ; loads sourcePath to rdi
xor rsi, rsi ; cleans rsi so open syscall doesnt try to use it as argument
mov rdx, O_RDONLY ; O_RDONLY
mov rax, SYS_OPEN ; open
syscall ; rax contains source fd (3)
push rax ; saving rax with source fd
;-----------------------------------------------------------------------------
; getting source file information to fstat struct
;-----------------------------------------------------------------------------
mov rdi, rax ; load rax (source fd = 3) to rdi
lea rsi, [fstat] ; load fstat struct to rsi
mov rax, SYS_FSTAT ; sys_fstat
syscall ; fstat struct conntains file information
mov r12, qword[rsi + 48] ; r12 contains file size in bytes (fstat.st_size)
;-----------------------------------------------------------------------------
; creating memory map for source file
;-----------------------------------------------------------------------------
pop rax ; restore rax containing source fd
mov r8, rax ; load r8 with source fd from rax
mov rax, SYS_MMAP ; mmap number
mov rdi, 0 ; operating system will choose mapping destination
mov rsi, r12 ; load rsi with page size from fstat.st_size in r12
mov rdx, 0x1 ; new memory region will be marked read only
mov r10, 0x2 ; pages will not be shared
mov r9, 0 ; offset inside source file
syscall ; now rax will point to mapped location
push rax ; saving rax with mmap address
;-----------------------------------------------------------------------------
; close source file
;-----------------------------------------------------------------------------
mov rdi, r8 ; load rdi with source fd from r8
mov rax, SYS_CLOSE ; close source fd
syscall
;-----------------------------------------------------------------------------
; creating memory fd with empty name ("")
;-----------------------------------------------------------------------------
lea rdi, [bogusName] ; empty string
mov rsi, MFD_CLOEXEC ; memfd mode
mov rax, SYS_MEMFD_CREATE
syscall ; memfd_create
mov rbx, rax ; memfd fd from rax to rbx
;-----------------------------------------------------------------------------
; writing memory map (source file) content to memory fd
;-----------------------------------------------------------------------------
pop rax ; restoring rax with mmap address
mov rdx, r12 ; rdx contains fstat.st_size from r12
mov rsi, rax ; load rsi with mmap address
mov rdi, rbx ; load memfd fd from rbx into rdi
mov rax, SYS_WRITE ; write buf to memfd fd
syscall
;-----------------------------------------------------------------------------
; executing memory fd with targetProcessName
;-----------------------------------------------------------------------------
xor rdx, rdx
lea rsi, [argv]
lea rdi, [fdPath]
mov rax, SYS_EXECVE ; execve the memfd fd in memory
syscall
;-----------------------------------------------------------------------------
; exit normally if everything works as expected
;-----------------------------------------------------------------------------
jmp normal_exit
;-----------------------------------------------------------------------------
; initialized data
;-----------------------------------------------------------------------------
segment readable writable
fstat STAT
usageMsg db "Usage: memrun <path_to_elf_file> <process_name>", 0xA, 0
sourcePath db 256 dup 0
targetProcessName db 256 dup 0
bogusName db "", 0
fdPath db "/proc/self/fd/3", 0
argv dd targetProcessName
================================================
FILE: assembly/struct.inc
================================================
; Macroinstructions for defining data structures
macro struct name
{ virtual at 0
define @struct
field@struct equ name
match child parent, name \{ restore field@struct
field@struct equ child,fields@\#parent \}
sub@struct equ
struc db [val] \{ \common define field@struct .,db,<val> \}
struc dw [val] \{ \common define field@struct .,dw,<val> \}
struc du [val] \{ \common define field@struct .,du,<val> \}
struc dd [val] \{ \common define field@struct .,dd,<val> \}
struc dp [val] \{ \common define field@struct .,dp,<val> \}
struc dq [val] \{ \common define field@struct .,dq,<val> \}
struc dt [val] \{ \common define field@struct .,dt,<val> \}
struc rb count \{ define field@struct .,db,count dup (?) \}
struc rw count \{ define field@struct .,dw,count dup (?) \}
struc rd count \{ define field@struct .,dd,count dup (?) \}
struc rp count \{ define field@struct .,dp,count dup (?) \}
struc rq count \{ define field@struct .,dq,count dup (?) \}
struc rt count \{ define field@struct .,dt,count dup (?) \}
macro db [val] \{ \common \local anonymous
define field@struct anonymous,db,<val> \}
macro dw [val] \{ \common \local anonymous
define field@struct anonymous,dw,<val> \}
macro du [val] \{ \common \local anonymous
define field@struct anonymous,du,<val> \}
macro dd [val] \{ \common \local anonymous
define field@struct anonymous,dd,<val> \}
macro dp [val] \{ \common \local anonymous
define field@struct anonymous,dp,<val> \}
macro dq [val] \{ \common \local anonymous
define field@struct anonymous,dq,<val> \}
macro dt [val] \{ \common \local anonymous
define field@struct anonymous,dt,<val> \}
macro rb count \{ \local anonymous
define field@struct anonymous,db,count dup (?) \}
macro rw count \{ \local anonymous
define field@struct anonymous,dw,count dup (?) \}
macro rd count \{ \local anonymous
define field@struct anonymous,dd,count dup (?) \}
macro rp count \{ \local anonymous
define field@struct anonymous,dp,count dup (?) \}
macro rq count \{ \local anonymous
define field@struct anonymous,dq,count dup (?) \}
macro rt count \{ \local anonymous
define field@struct anonymous,dt,count dup (?) \}
macro union \{ field@struct equ ,union,<
sub@struct equ union \}
macro struct \{ field@struct equ ,substruct,<
sub@struct equ substruct \} }
macro ends
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
restruc rb,rw,rd,rp,rq,rt
purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt
purge union,struct
irpv fields,field@struct \\{ restore field@struct
\\common define fields@struct fields \\}
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ restore @struct
make@struct name,fields
define fields@\\#name fields \\}
end virtual \}
match any, sub@struct \{ tmp@struct equ field@struct
restore field@struct
field@struct equ tmp@struct> \}
restore sub@struct }
macro make@struct name,[field,type,def]
{ common
local define
define equ name
forward
local sub
match , field \{ make@substruct type,name,sub def
define equ define,.,sub, \}
match any, field \{ define equ define,.#field,type,<def> \}
common
match fields, define \{ define@struct fields \} }
macro define@struct name,[field,type,def]
{ common
virtual
db `name
load initial@struct byte from 0
if initial@struct = '.'
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
err
end if
end virtual
local list
list equ
forward
if ~ field eq .
name#field type def
sizeof.#name#field = $ - name#field
else
label name#.#type
rb sizeof.#type
end if
local value
match any, list \{ list equ list, \}
list equ list <value>
common
sizeof.#name = $
restruc name
match values, list \{
struc name value \\{ \\local \\..base
match , @struct \\\{ define field@struct .,name,<values> \\\}
match no, @struct \\\{ label \\..base
forward
match , value \\\\{ field type def \\\\}
match any, value \\\\{ field type value
if ~ field eq .
rb sizeof.#name#field - ($-field)
end if \\\\}
common label . at \\..base \\\}
\\}
macro name value \\{
match , @struct \\\{ \\\local anonymous
define field@struct anonymous,name,<values> \\\}
match no, @struct \\\{
forward
match , value \\\\{ type def \\\\}
match any, value \\\\{ \\\\local ..field
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
common \\\} \\} \} }
macro enable@substruct
{ macro make@substruct substruct,parent,name,[field,type,def]
\{ \common
\local define
define equ parent,name
\forward
\local sub
match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,parent,sub def
purge make@substruct
define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\}
\common
match fields, define \\{ define@\#substruct fields \\} \} }
enable@substruct
macro define@union parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
virtual at parent#.#name
parent#field type def
sizeof.#parent#field = $ - parent#field
end virtual
if sizeof.#parent#field > $ - parent#.#name
rb sizeof.#parent#field - ($ - parent#.#name)
end if
else
virtual at parent#.#name
label parent#.#type
type def
end virtual
label name#.#type at parent#.#name
if sizeof.#type > $ - parent#.#name
rb sizeof.#type - ($ - parent#.#name)
end if
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name [value] \{ \common
label .\#name
last@union equ
forward
match any, last@union \\{ virtual at .\#name
field type def
end virtual \\}
match , last@union \\{ match , value \\\{ field type def \\\}
match any, value \\\{ field type value \\\} \\}
last@union equ field
common rb sizeof.#name - ($ - .\#name) \}
macro name [value] \{ \common \local ..anonymous
..anonymous name value \} }
macro define@substruct parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
local value
if ~ field eq .
parent#field type def
sizeof.#parent#field = $ - parent#field
else
label parent#.#type
rb sizeof.#type
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name value \{
label .\#name
forward
match , value \\{ field type def \\}
match any, value \\{ field type value
if ~ field eq .
rb sizeof.#parent#field - ($-field)
end if \\}
common \}
macro name value \{ \local ..anonymous
..anonymous name \} }
================================================
FILE: assembly/utils.inc
================================================
SYS_EXIT = 60
SYS_OPEN = 2
SYS_CLOSE = 3
SYS_WRITE = 1
SYS_READ = 0
SYS_STAT = 4
SYS_MEMFD_CREATE = 319
SYS_EXECVE = 59
SYS_FSTAT = 5
SYS_MMAP = 9
O_RDONLY = 0
MFD_CLOEXEC = 1
struct STAT
st_dev dw ? ; ID of device containing file
pad1 dw ?
st_ino dd ? ; inode number
st_mode dw ? ; protection
st_nlink dw ? ; number of hard links
st_uid dw ? ; user ID of owner
st_gid dw ? ; group ID of owner
st_rdev dw ? ; device ID (if special file)
pad2 dw ?
st_size dd ? ; total size, in bytes
st_blksize dd ? ; block size
st_blocks dd ?
st_atime dd ? ; time of last access
unused1 dd ?
st_mtime dd ? ; time of last modification
unused2 dd ?
st_ctime dd ? ; time of last status change
unused3 dd ?
unused4 dd ?
unused5 dd ?
ends
normal_exit:
xor rdi, rdi ; exit code 0
mov rax, SYS_EXIT ; sys_exit
syscall
bad_exit:
mov rdi, 1
mov rax, SYS_EXIT
syscall
usage:
lea rdi, [usageMsg]
call print
jmp bad_exit
strlen: ; rdi is the default search for scasb
push rdi
push rcx
mov rcx, -1
xor eax, eax
repne scasb
not rcx
mov rax, rcx
pop rcx
pop rdi
ret
print:
push rsi
push rdx
push rdi
call strlen
mov rdx, rax
mov rsi, rdi
mov rdi, 1
mov rax, SYS_WRITE
syscall
pop rsi
pop rdx
pop rdi
ret
strToVar:
mov al, [rsi]
mov [rdi], al
inc rsi
inc rdi
cmp byte [rsi], 0 ; Check for null terminator
jne strToVar ; loop if not null
ret
================================================
FILE: memrun.go
================================================
package main
import (
"fmt"
"io/ioutil"
"os"
"syscall"
"unsafe"
)
// the constant values below are valid for x86_64
const (
mfdCloexec = 0x0001
memfdCreate = 319
)
func runFromMemory(displayName string, filePath string) {
fdName := "" // *string cannot be initialized
fd, _, _ := syscall.Syscall(memfdCreate, uintptr(unsafe.Pointer(&fdName)), uintptr(mfdCloexec), 0)
buffer, _ := ioutil.ReadFile(filePath)
_, _ = syscall.Write(int(fd), buffer)
fdPath := fmt.Sprintf("/proc/self/fd/%d", fd)
_ = syscall.Exec(fdPath, []string{displayName}, nil)
}
func main() {
lenArgs := len(os.Args)
if lenArgs < 3 || lenArgs > 3 {
fmt.Println("Usage: memrun process_name elf_binary")
os.Exit(1)
}
runFromMemory(os.Args[1], os.Args[2])
}
gitextract_cb4r4ys1/ ├── .gitattributes ├── LICENSE ├── README.md ├── assembly/ │ ├── README.md │ ├── memrun.asm │ ├── struct.inc │ └── utils.inc └── memrun.go
SYMBOL INDEX (4 symbols across 1 files)
FILE: memrun.go
constant mfdCloexec (line 13) | mfdCloexec = 0x0001
constant memfdCreate (line 14) | memfdCreate = 319
function runFromMemory (line 17) | func runFromMemory(displayName string, filePath string) {
function main (line 28) | func main() {
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (19K chars).
[
{
"path": ".gitattributes",
"chars": 42,
"preview": "assembly/*.inc linguist-language=Assembly\n"
},
{
"path": "LICENSE",
"chars": 1085,
"preview": "MIT License\n\nCopyright (c) 2018 Guilherme Thomazi Bonicontro\n\nPermission is hereby granted, free of charge, to any perso"
},
{
"path": "README.md",
"chars": 478,
"preview": "# memrun\nSmall tool written in Golang to run ELF (x86_64) binaries from memory with a given process name. Works on Linux"
},
{
"path": "assembly/README.md",
"chars": 500,
"preview": "# memrun\nSmall tool written in Assembly (FASM) to run ELF (x86_64) binaries from memory with a given process name. Works"
},
{
"path": "assembly/memrun.asm",
"chars": 5198,
"preview": "format ELF64 executable 3\n\ninclude \"struct.inc\"\ninclude \"utils.inc\"\n\nsegment readable executable\nentry start\n\nstart:\n;--"
},
{
"path": "assembly/struct.inc",
"chars": 7190,
"preview": "\n; Macroinstructions for defining data structures\n\nmacro struct name\n { virtual at 0\n define @struct\n field@struct e"
},
{
"path": "assembly/utils.inc",
"chars": 1968,
"preview": "SYS_EXIT = 60\nSYS_OPEN = 2\nSYS_CLOSE = 3\nSYS_WRITE = 1\nSYS_READ = 0"
},
{
"path": "memrun.go",
"chars": 750,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// the constant values below are valid for x86_"
}
]
About this extraction
This page contains the full source code of the guitmz/memrun GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (16.8 KB), approximately 4.6k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.