Created
April 29, 2018 15:31
-
-
Save niallnsec/1ffc71faa8d1f6a9ceaf27492ceadb8c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"fmt" | |
"log" | |
"strings" | |
"syscall" | |
"unsafe" | |
) | |
var ( | |
modkernel32 = syscall.NewLazyDLL("kernel32.dll") | |
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") | |
procGetProcessId = modkernel32.NewProc("GetProcessId") | |
modntdll = syscall.NewLazyDLL("ntdll.dll") | |
procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") | |
errNoSuchProcess = errors.New("no such process") | |
) | |
type ( | |
UNICODE_STRING struct { | |
Length uint16 | |
MaxLangth uint16 | |
Buffer uintptr | |
} | |
WindowsProcess struct { | |
hProcess *syscall.Handle | |
processID uint32 | |
pProcessID uint32 | |
processName string | |
} | |
PROCESS_BASIC_INFORMATION struct { | |
ExitStatus uintptr | |
PebBaseAddress uintptr | |
AffinityMask uintptr | |
BasePriority uintptr | |
UniqueProcessId uintptr | |
InheritedFromUniqueProcessId uintptr | |
} | |
) | |
func main() { | |
hProcess, err := getProcessHandle("Notepad.exe", syscall.PROCESS_QUERY_INFORMATION|8|16) | |
if err != nil { | |
panic(err.Error()) | |
} | |
wp := NewWindowsProcess(*hProcess) | |
pid, err := wp.ProcessID() | |
if err != nil { | |
panic(err.Error()) | |
} | |
fmt.Printf("PID: %d\n", pid) | |
var pbi PROCESS_BASIC_INFORMATION | |
var retLen uint32 | |
err = NtQueryInformationProcess(*hProcess, 0, &pbi, unsafe.Sizeof(pbi), &retLen) | |
if err != nil { | |
panic(err.Error()) | |
} | |
fmt.Printf("Base Addr: %x\n", pbi.PebBaseAddress) | |
fmt.Printf("ProcID: %x\n", pbi.UniqueProcessId) | |
var procParams uint64 | |
var br uint32 | |
err = ReadProcessMemory(*hProcess, pbi.PebBaseAddress+32, uintptr(unsafe.Pointer(&procParams)), unsafe.Sizeof(procParams), uintptr(unsafe.Pointer(&br))) | |
if err != nil { | |
panic(err.Error()) | |
} | |
fmt.Printf("Params: %x\n", procParams) | |
var pCmdLine UNICODE_STRING | |
err = ReadProcessMemory(*hProcess, uintptr(procParams+112), uintptr(unsafe.Pointer(&pCmdLine)), unsafe.Sizeof(pCmdLine), uintptr(unsafe.Pointer(&br))) | |
if err != nil { | |
panic(err.Error()) | |
} | |
fmt.Printf("CMD Line: %x\n", pCmdLine.Buffer) | |
fmt.Printf("L HProc: %x\n", *hProcess) | |
fmt.Printf("L PBuffer: %x\n", pCmdLine.Buffer) | |
fmt.Printf("L BLength: %x\n", pCmdLine.Length) | |
var sparameter = make([]uint16, pCmdLine.Length/2, pCmdLine.Length/2) | |
err = ReadProcessMemory(*hProcess, pCmdLine.Buffer, uintptr(unsafe.Pointer(&sparameter[0])), uintptr(pCmdLine.Length), uintptr(unsafe.Pointer(&br))) | |
if err != nil { | |
panic(err.Error()) | |
} | |
sCmdLine := syscall.UTF16ToString(sparameter) | |
ssCmdLine, err := pCmdLine.StringRemote(hProcess) | |
if err != nil { | |
panic(err.Error()) | |
} | |
fmt.Printf("CMD Line: %s\n", sCmdLine) | |
fmt.Printf("CMD Line: %s\n", ssCmdLine) | |
syscall.CloseHandle(*hProcess) | |
} | |
func (us UNICODE_STRING) StringRemote(hProcess *syscall.Handle) (string, error) { | |
var br uint32 | |
fmt.Printf("R HProc: %x\n", *hProcess) | |
fmt.Printf("R PBuffer: %x\n", us.Buffer) | |
fmt.Printf("R BLength: %x\n", us.Length) | |
//fmt.Println(br) | |
var sparameter = make([]uint16, us.Length/2, us.Length/2) | |
err := ReadProcessMemory(*hProcess, us.Buffer, uintptr(unsafe.Pointer(&sparameter[0])), uintptr(us.Length), uintptr(unsafe.Pointer(&br))) | |
if err != nil { | |
return "", err | |
} | |
s := syscall.UTF16ToString(sparameter) | |
return s, nil | |
} | |
func NewWindowsProcess(hProc syscall.Handle) *WindowsProcess { | |
return &WindowsProcess{ | |
hProcess: &hProc, | |
} | |
} | |
func (wp *WindowsProcess) ProcessID() (uint32, error) { | |
if wp.processID == 0 { | |
pid, err := GetProcessId(*wp.hProcess) | |
if pid == 0 { | |
return 0, err | |
} | |
wp.processID = pid | |
} | |
return wp.processID, nil | |
} | |
func NtQueryInformationProcess(ProcessHandle syscall.Handle, ProcessInformationClass uint32, | |
ProcessInformation *PROCESS_BASIC_INFORMATION, ProcessInformationLength uintptr, ReturnLength *uint32) error { | |
r1, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(ProcessHandle), | |
uintptr(ProcessInformationClass), uintptr(unsafe.Pointer(ProcessInformation)), ProcessInformationLength, | |
uintptr(unsafe.Pointer(ReturnLength)), 0) | |
if r1 != 0 { | |
fmt.Println(r1) | |
return errors.New(e1.Error()) | |
} | |
return nil | |
} | |
func GetProcessId(hProcess syscall.Handle) (uint32, error) { | |
r1, _, e1 := syscall.Syscall(procGetProcessId.Addr(), 1, uintptr(hProcess), 0, 0) | |
if r1 == 0 { | |
return 0, errors.New(e1.Error()) | |
} | |
return uint32(r1), nil | |
} | |
func ReadProcessMemory(hProcess syscall.Handle, lpBaseAddress uintptr, lpBuffer uintptr, nSize uintptr, | |
lpNumberOfBytesRead uintptr) error { | |
r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(hProcess), lpBaseAddress, | |
lpBuffer, nSize, lpNumberOfBytesRead, 0) | |
if r1 == 0 { | |
return errors.New(e1.Error()) | |
} | |
return nil | |
} | |
func getProcessHandle(pName string, access int) (*syscall.Handle, error) { | |
hSnapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) | |
if err != nil { | |
rerr := fmt.Errorf("error creating process snapshot: %s", err.Error()) | |
log.Printf(rerr.Error()) | |
return nil, rerr | |
} | |
var proc syscall.ProcessEntry32 | |
proc.Size = uint32(unsafe.Sizeof(proc)) | |
err = syscall.Process32First(hSnapshot, &proc) | |
if err != nil { | |
rerr := fmt.Errorf("error reading process snapshot: %s", err.Error()) | |
log.Printf(rerr.Error()) | |
return nil, rerr | |
} | |
pName = strings.ToLower(pName) | |
for { | |
sexe := syscall.UTF16ToString(proc.ExeFile[:]) | |
if strings.ToLower(sexe) == pName { | |
hProcess, err := syscall.OpenProcess(uint32(access), false, proc.ProcessID) | |
if err != nil { | |
rerr := fmt.Errorf("error opening process: %s", err.Error()) | |
log.Printf(rerr.Error()) | |
return nil, rerr | |
} | |
return &hProcess, nil | |
} | |
err = syscall.Process32Next(hSnapshot, &proc) | |
if err != nil { | |
if err.Error() == "There are no more files." { | |
break | |
} | |
return nil, err | |
} | |
} | |
log.Printf(errNoSuchProcess.Error()) | |
return nil, errNoSuchProcess | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment