mirror of
https://github.com/rainerzufalldererste/windows_x64_shellcode_template
synced 2026-06-08 16:57:13 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = crlf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Project & Solution Files
|
||||
*.sln
|
||||
*.vcxpro*
|
||||
|
||||
# Visual Studio Code configuration files
|
||||
*.vscode/
|
||||
|
||||
# Makefile
|
||||
Makefile
|
||||
*.make
|
||||
|
||||
# Additional Files
|
||||
mediaLib/lib/*.lib
|
||||
htCodec/3rdParty/rans_static/lib/*
|
||||
enc_temp_folder/*
|
||||
builds/*
|
||||
* Advisor Result*/
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "premake"]
|
||||
path = premake
|
||||
url = https://github.com/rainerzufalldererste/premakeBuild.git
|
||||
@@ -0,0 +1,188 @@
|
||||
# Shellcode Template for Windows x64
|
||||
An easily modifiable shellcode template that loads `LoadLibraryA` and `GetProcAddress` and exposes the `HMODULE` to `kernel32.dll` written in C.
|
||||
|
||||
There are a lot of comments in the `shellcode_template` function to better explain what's going on. If you don't want to clone the repository, here's the important part:
|
||||
|
||||
```c
|
||||
// Load Process Environment Block.
|
||||
PEB *pProcessEnvironmentBlock = (PEB *)__readgsqword(0x60);
|
||||
|
||||
// `pProcessEnvironmentBlock->Ldr->InMemoryOrderModuleList` contains a double linked list.
|
||||
// `Flink` and `Blink` are the pointers to the next element.
|
||||
//
|
||||
// All Windows executables should have the following module order.
|
||||
// 1. The module of the current executable.
|
||||
// 2. `ntdll.dll` (`%windir%\System32\ntdll.dll`)
|
||||
// 3. `kernel32.dll` (`%windir%\System32\kernel32.dll`)
|
||||
//
|
||||
// ... followed by other modules.
|
||||
//
|
||||
// In order to get the `GetProcAddress` function we need to therefore get the third item (`Flink->Flink->Flink`).
|
||||
// We use the `CONTAINING_RECORD` macro to retrieve the associated table entry.
|
||||
LDR_DATA_TABLE_ENTRY *pKernel32TableEntry = CONTAINING_RECORD(pProcessEnvironmentBlock->Ldr->InMemoryOrderModuleList.Flink->Flink->Flink, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
|
||||
|
||||
// We've ended up at the base address of `kernel32.dll`.
|
||||
IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pKernel32TableEntry->DllBase;
|
||||
|
||||
// In order to get the exported functions we need to go to the NT PE header.
|
||||
IMAGE_NT_HEADERS *pNtHeader = (IMAGE_NT_HEADERS *)((uint8_t *)pDosHeader + pDosHeader->e_lfanew);
|
||||
|
||||
// From the NtHeader we can extract the virtual address of the export directory of this module.
|
||||
IMAGE_EXPORT_DIRECTORY *pExports = (IMAGE_EXPORT_DIRECTORY *)((uint8_t *)pDosHeader + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
|
||||
// The exports directory contains both a list of function _names_ of this module and the associated _addresses_ of the functions.
|
||||
const int32_t *pNameOffsets = (const int32_t *)((uint8_t *)pDosHeader + pExports->AddressOfNames);
|
||||
|
||||
// We will use this struct to store strings.
|
||||
// We are using a struct to make sure strings don't end up in another section of the executable where we wouldn't be able to address them in a different process.
|
||||
struct
|
||||
{
|
||||
uint64_t text0, text1;
|
||||
} x;
|
||||
|
||||
// We're now looking for the `GetProcAddress` function. Since there's no other function starting with `GetProcA` we'll just find that instead.
|
||||
x.text0 = 0x41636F7250746547; // `GetProcA`
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
// We're just extracting the first 8 bytes of the strings and compare them to `GetProcA`. We'll find it eventually.
|
||||
while (*(uint64_t *)((char *)pDosHeader + pNameOffsets[i]) != x.text0)
|
||||
++i;
|
||||
|
||||
// We have found the index of `GetProcAddress`.
|
||||
|
||||
// Not let's get the function offsets in order to retrieve the location of `GetProcAddress` in memory.
|
||||
const int32_t *pFunctionOffsets = (const int32_t *)((uint8_t *)pDosHeader + pExports->AddressOfFunctions);
|
||||
|
||||
typedef FARPROC(*GetProcAddressFunc)(HMODULE, const char *);
|
||||
GetProcAddressFunc pGetProcAddress = (GetProcAddressFunc)(const void *)((uint8_t *)pDosHeader + pFunctionOffsets[i]);
|
||||
|
||||
// Now that we've got `GetProcAddress`, let's use it to get `LoadLibraryA`.
|
||||
|
||||
// A HMODULE is just a pointer to the base address of a module.
|
||||
HMODULE kernel32Dll = (HMODULE)pDosHeader;
|
||||
|
||||
// Get `LoadLibraryA`.
|
||||
x.text0 = 0x7262694C64616F4C; // `LoadLibr`
|
||||
x.text1 = 0x0000000041797261; // `aryA\0\0\0\0`
|
||||
|
||||
typedef HMODULE(*LoadLibraryAFunc)(const char *);
|
||||
LoadLibraryAFunc pLoadLibraryA = (LoadLibraryAFunc)pGetProcAddress(kernel32Dll, (const char *)&x.text0);
|
||||
```
|
||||
|
||||
There's also an example application that demonstrates how the generated shellcode can be executed inside a child process.
|
||||
|
||||
### Get Started
|
||||
```bash
|
||||
git clone https://github.com/rainerzufalldererste/windows_x64_shellcode_template.git
|
||||
cd windows_x64_shellcode_template
|
||||
git submodule update --init --recursive
|
||||
create_project.bat
|
||||
```
|
||||
Choose your compiler toolset. (VS 2015 / VS 2017)
|
||||
|
||||
|
||||
The `shellcode_template` project includes everything to start developing custom shellcode.
|
||||
|
||||
### How to retrieve the shellcode?
|
||||
There are many ways to retrieve the generated shellcode. An easy way is to just paste your code into an online compiler like [godbolt.org](https://godbolt.org/) and copy the generated MSVC assembly (ie. `x64 msvc v19.21`) into an online assembler like [https://defuse.ca/online-x86-assembler.htm](https://defuse.ca/online-x86-assembler.htm). Then just copy the generated shellcode.
|
||||
|
||||
You will probably have to clean up the assembly a bit, like this:
|
||||
|
||||
```asm
|
||||
x$ = 32
|
||||
void shellcode_template(void) PROC ; shellcode_template, COMDAT
|
||||
$LN10:
|
||||
mov QWORD PTR [rsp+8], rbx
|
||||
push rdi
|
||||
sub rsp, 48 ; 00000030H
|
||||
mov rax, QWORD PTR gs:96
|
||||
xor edx, edx
|
||||
mov r9, 4711732171926431047 ; 41636f7250746547H
|
||||
mov rcx, QWORD PTR [rax+24]
|
||||
mov rax, QWORD PTR [rcx+32]
|
||||
mov rcx, QWORD PTR [rax]
|
||||
mov rax, QWORD PTR [rcx]
|
||||
mov rdi, QWORD PTR [rax+32]
|
||||
movsxd rax, DWORD PTR [rdi+60]
|
||||
mov r8d, DWORD PTR [rax+rdi+136]
|
||||
mov eax, DWORD PTR [r8+rdi+32]
|
||||
add rax, rdi
|
||||
movsxd rcx, DWORD PTR [rax]
|
||||
cmp QWORD PTR [rcx+rdi], r9
|
||||
je SHORT $LN3@shellcode_
|
||||
npad 2
|
||||
$LL2@shellcode_:
|
||||
movsxd rcx, DWORD PTR [rax+4]
|
||||
lea rax, QWORD PTR [rax+4]
|
||||
inc edx
|
||||
...
|
||||
```
|
||||
|
||||
can through a bit of find and replace be turned into this:
|
||||
|
||||
```asm
|
||||
shellcode_template:
|
||||
mov qword ptr [rsp+8], rbx
|
||||
push rdi
|
||||
sub rsp, 48
|
||||
mov rax, qword ptr gs:96
|
||||
xor edx, edx
|
||||
mov r9, 4711732171926431047
|
||||
mov rcx, qword ptr [rax+24]
|
||||
mov rax, qword ptr [rcx+32]
|
||||
mov rcx, qword ptr [rax]
|
||||
mov rax, qword ptr [rcx]
|
||||
mov rdi, qword ptr [rax+32]
|
||||
movsxd rax, dword ptr [rdi+60]
|
||||
mov r8d, dword ptr [rax+rdi+136]
|
||||
mov eax, dword ptr [r8+rdi+32]
|
||||
add rax, rdi
|
||||
movsxd rcx, dword ptr [rax]
|
||||
cmp qword ptr [rcx+rdi], r9
|
||||
je short _function_found
|
||||
|
||||
; `npad 2` can be turned into two `nop`s.
|
||||
|
||||
nop
|
||||
nop
|
||||
|
||||
_check_next_function_name:
|
||||
movsxd rcx, dword ptr [rax+4]
|
||||
lea rax, qword ptr [rax+4]
|
||||
inc edx
|
||||
...
|
||||
```
|
||||
|
||||
### Just interested in the generated shellcode?
|
||||
This is the example shellcode. It performs the following actions:
|
||||
+ It finds `GetProcAddress` in `kernel32.dll`,
|
||||
+ retrieves `LoadLibraryA` from `kernel32.dll`,
|
||||
+ loads `user32.dll`,
|
||||
+ retrieves `MessageBoxA` from `user32.dll`,
|
||||
+ displays a message box,
|
||||
+ retrieves `ExitProcess` from `kernel32.dll`,
|
||||
+ calls `ExitProcess`.
|
||||
|
||||
```
|
||||
0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 0x48, 0x83, 0xEC, 0x30, 0x65, 0x48, 0x8B, 0x04, 0x25, 0x60,
|
||||
0x00, 0x00, 0x00, 0x31, 0xD2, 0x49, 0xB9, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x41, 0x48,
|
||||
0x8B, 0x48, 0x18, 0x48, 0x8B, 0x41, 0x20, 0x48, 0x8B, 0x08, 0x48, 0x8B, 0x01, 0x48, 0x8B, 0x78,
|
||||
0x20, 0x48, 0x63, 0x47, 0x3C, 0x44, 0x8B, 0x84, 0x38, 0x88, 0x00, 0x00, 0x00, 0x41, 0x8B, 0x44,
|
||||
0x38, 0x20, 0x48, 0x01, 0xF8, 0x48, 0x63, 0x08, 0x4C, 0x39, 0x0C, 0x39, 0x74, 0x12, 0x90, 0x90,
|
||||
0x48, 0x63, 0x48, 0x04, 0x48, 0x8D, 0x40, 0x04, 0xFF, 0xC2, 0x4C, 0x39, 0x0C, 0x39, 0x75, 0xF0,
|
||||
0x41, 0x8B, 0x4C, 0x38, 0x1C, 0x48, 0xB8, 0x4C, 0x6F, 0x61, 0x64, 0x4C, 0x69, 0x62, 0x72, 0x48,
|
||||
0x01, 0xF9, 0x48, 0x63, 0xD2, 0x48, 0x63, 0x1C, 0x91, 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0x01,
|
||||
0xFB, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0x89, 0xF9, 0x48, 0xC7, 0x44, 0x24, 0x28, 0x61, 0x72,
|
||||
0x79, 0x41, 0xFF, 0xD3, 0x48, 0xB9, 0x75, 0x73, 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x48, 0xC7,
|
||||
0x44, 0x24, 0x28, 0x6C, 0x6C, 0x00, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8D, 0x4C, 0x24,
|
||||
0x20, 0xFF, 0xD0, 0x48, 0xB9, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x48, 0xC7, 0x44,
|
||||
0x24, 0x28, 0x6F, 0x78, 0x41, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8D, 0x54, 0x24, 0x20,
|
||||
0x48, 0x89, 0xC1, 0xFF, 0xD3, 0x48, 0xB9, 0x48, 0x61, 0x73, 0x74, 0x61, 0x20, 0x6C, 0x61, 0x4C,
|
||||
0x8D, 0x44, 0x24, 0x2F, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0xB9,
|
||||
0x20, 0x76, 0x69, 0x73, 0x74, 0x61, 0x21, 0x00, 0x45, 0x31, 0xC9, 0x48, 0x89, 0x4C, 0x24, 0x28,
|
||||
0x31, 0xC9, 0xFF, 0xD0, 0x48, 0xB8, 0x45, 0x78, 0x69, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x48, 0xC7,
|
||||
0x44, 0x24, 0x28, 0x65, 0x73, 0x73, 0x00, 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0x89, 0x44, 0x24,
|
||||
0x20, 0x48, 0x89, 0xF9, 0xFF, 0xD3, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x48, 0x8B, 0x5C,
|
||||
0x24, 0x40, 0x48, 0x83, 0xC4, 0x30, 0x5F, 0xC2, 0x00, 0x00
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
@ECHO OFF
|
||||
|
||||
IF [%1]==[] GOTO MANUAL_CONFIG
|
||||
|
||||
IF "%1"=="1" GOTO ONE;
|
||||
IF "%1"=="2" GOTO TWO;
|
||||
IF "%1"=="3" GOTO THREE;
|
||||
IF "%1"=="4" GOTO FOUR;
|
||||
|
||||
ECHO INVALID PARAMETER (%1)
|
||||
|
||||
:MANUAL_CONFIG
|
||||
ECHO 1. Visual Studio 2017 Solution
|
||||
ECHO 2. Visual Studio 2015 Solution
|
||||
ECHO 3. Visual Studio 2013 Solution
|
||||
ECHO 4. gmake2 Makefile
|
||||
|
||||
CHOICE /N /C:1234 /M "[1-4]:"
|
||||
|
||||
IF ERRORLEVEL ==4 GOTO FOUR
|
||||
IF ERRORLEVEL ==3 GOTO THREE
|
||||
IF ERRORLEVEL ==2 GOTO TWO
|
||||
IF ERRORLEVEL ==1 GOTO ONE
|
||||
GOTO END
|
||||
|
||||
:FOUR
|
||||
ECHO Creating gmake2 Makefile...
|
||||
premake\premake5.exe gmake2
|
||||
GOTO END
|
||||
|
||||
:THREE
|
||||
ECHO Creating VS2013 Project...
|
||||
premake\premake5.exe vs2013
|
||||
GOTO END
|
||||
|
||||
:TWO
|
||||
ECHO Creating VS2015 Project...
|
||||
premake\premake5.exe vs2015
|
||||
GOTO END
|
||||
|
||||
:ONE
|
||||
ECHO Creating VS2017 Project...
|
||||
premake\premake5.exe vs2017
|
||||
GOTO END
|
||||
|
||||
:END
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
ProjectName = "child_process"
|
||||
project(ProjectName)
|
||||
|
||||
--Settings
|
||||
kind "ConsoleApp"
|
||||
language "C"
|
||||
flags { "StaticRuntime", "FatalWarnings" }
|
||||
|
||||
defines { "_CRT_SECURE_NO_WARNINGS" }
|
||||
|
||||
objdir "intermediate/obj"
|
||||
|
||||
files { "src/**.c", "src/**.cpp", "src/**.h", "src/**.inl", "src/**rc" }
|
||||
files { "project.lua" }
|
||||
|
||||
includedirs { "src" }
|
||||
|
||||
targetname(ProjectName)
|
||||
targetdir "../../builds/bin"
|
||||
debugdir "../../builds/bin"
|
||||
|
||||
filter { "configurations:Debug", "system:Windows" }
|
||||
ignoredefaultlibraries { "libcmt" }
|
||||
filter { }
|
||||
|
||||
filter {}
|
||||
configuration {}
|
||||
|
||||
warnings "Extra"
|
||||
|
||||
filter {"configurations:Release"}
|
||||
targetname "%{prj.name}"
|
||||
filter {"configurations:Debug"}
|
||||
targetname "%{prj.name}D"
|
||||
|
||||
filter { }
|
||||
flags { "NoPCH" }
|
||||
exceptionhandling "Off"
|
||||
rtti "Off"
|
||||
floatingpoint "Fast"
|
||||
|
||||
filter { "configurations:Debug*" }
|
||||
defines { "_DEBUG" }
|
||||
symbols "FastLink"
|
||||
|
||||
filter { "configurations:Release" }
|
||||
defines { "NDEBUG" }
|
||||
optimize "Speed"
|
||||
flags { "NoFramePointer", "NoBufferSecurityCheck", "NoIncrementalLink" }
|
||||
editandcontinue "Off"
|
||||
symbols "On"
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
int32_t main()
|
||||
{
|
||||
int32_t lives = 60;
|
||||
|
||||
while (--lives)
|
||||
{
|
||||
puts("Ah, ha, ha, ha, stayin' alive, stayin' alive");
|
||||
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
ProjectName = "host_process"
|
||||
project(ProjectName)
|
||||
|
||||
--Settings
|
||||
kind "ConsoleApp"
|
||||
language "C"
|
||||
flags { "StaticRuntime", "FatalWarnings" }
|
||||
|
||||
dependson { "child_process" }
|
||||
|
||||
defines { "_CRT_SECURE_NO_WARNINGS" }
|
||||
|
||||
objdir "intermediate/obj"
|
||||
|
||||
files { "src/**.c", "src/**.cpp", "src/**.h", "src/**.inl", "src/**rc" }
|
||||
files { "project.lua" }
|
||||
|
||||
includedirs { "src" }
|
||||
|
||||
targetname(ProjectName)
|
||||
targetdir "../../builds/bin"
|
||||
debugdir "../../builds/bin"
|
||||
|
||||
filter { "configurations:Debug", "system:Windows" }
|
||||
ignoredefaultlibraries { "libcmt" }
|
||||
filter { }
|
||||
|
||||
filter {}
|
||||
configuration {}
|
||||
|
||||
warnings "Extra"
|
||||
|
||||
filter {"configurations:Release"}
|
||||
targetname "%{prj.name}"
|
||||
filter {"configurations:Debug"}
|
||||
targetname "%{prj.name}D"
|
||||
|
||||
filter { }
|
||||
flags { "NoPCH" }
|
||||
exceptionhandling "Off"
|
||||
rtti "Off"
|
||||
floatingpoint "Fast"
|
||||
|
||||
filter { "configurations:Debug*" }
|
||||
defines { "_DEBUG" }
|
||||
symbols "FastLink"
|
||||
|
||||
filter { "configurations:Release" }
|
||||
defines { "NDEBUG" }
|
||||
optimize "Speed"
|
||||
flags { "NoFramePointer", "NoBufferSecurityCheck", "NoIncrementalLink" }
|
||||
editandcontinue "Off"
|
||||
symbols "On"
|
||||
@@ -0,0 +1,105 @@
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <memoryapi.h>
|
||||
|
||||
const uint8_t shellcode[] = {
|
||||
0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 0x48, 0x83, 0xEC, 0x30, 0x65, 0x48, 0x8B, 0x04, 0x25, 0x60,
|
||||
0x00, 0x00, 0x00, 0x31, 0xD2, 0x49, 0xB9, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x41, 0x48,
|
||||
0x8B, 0x48, 0x18, 0x48, 0x8B, 0x41, 0x20, 0x48, 0x8B, 0x08, 0x48, 0x8B, 0x01, 0x48, 0x8B, 0x78,
|
||||
0x20, 0x48, 0x63, 0x47, 0x3C, 0x44, 0x8B, 0x84, 0x38, 0x88, 0x00, 0x00, 0x00, 0x41, 0x8B, 0x44,
|
||||
0x38, 0x20, 0x48, 0x01, 0xF8, 0x48, 0x63, 0x08, 0x4C, 0x39, 0x0C, 0x39, 0x74, 0x12, 0x90, 0x90,
|
||||
0x48, 0x63, 0x48, 0x04, 0x48, 0x8D, 0x40, 0x04, 0xFF, 0xC2, 0x4C, 0x39, 0x0C, 0x39, 0x75, 0xF0,
|
||||
0x41, 0x8B, 0x4C, 0x38, 0x1C, 0x48, 0xB8, 0x4C, 0x6F, 0x61, 0x64, 0x4C, 0x69, 0x62, 0x72, 0x48,
|
||||
0x01, 0xF9, 0x48, 0x63, 0xD2, 0x48, 0x63, 0x1C, 0x91, 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0x01,
|
||||
0xFB, 0x48, 0x89, 0x44, 0x24, 0x20, 0x48, 0x89, 0xF9, 0x48, 0xC7, 0x44, 0x24, 0x28, 0x61, 0x72,
|
||||
0x79, 0x41, 0xFF, 0xD3, 0x48, 0xB9, 0x75, 0x73, 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x48, 0xC7,
|
||||
0x44, 0x24, 0x28, 0x6C, 0x6C, 0x00, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8D, 0x4C, 0x24,
|
||||
0x20, 0xFF, 0xD0, 0x48, 0xB9, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x48, 0xC7, 0x44,
|
||||
0x24, 0x28, 0x6F, 0x78, 0x41, 0x00, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8D, 0x54, 0x24, 0x20,
|
||||
0x48, 0x89, 0xC1, 0xFF, 0xD3, 0x48, 0xB9, 0x48, 0x61, 0x73, 0x74, 0x61, 0x20, 0x6C, 0x61, 0x4C,
|
||||
0x8D, 0x44, 0x24, 0x2F, 0x48, 0x89, 0x4C, 0x24, 0x20, 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0xB9,
|
||||
0x20, 0x76, 0x69, 0x73, 0x74, 0x61, 0x21, 0x00, 0x45, 0x31, 0xC9, 0x48, 0x89, 0x4C, 0x24, 0x28,
|
||||
0x31, 0xC9, 0xFF, 0xD0, 0x48, 0xB8, 0x45, 0x78, 0x69, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x48, 0xC7,
|
||||
0x44, 0x24, 0x28, 0x65, 0x73, 0x73, 0x00, 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0x89, 0x44, 0x24,
|
||||
0x20, 0x48, 0x89, 0xF9, 0xFF, 0xD3, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x48, 0x8B, 0x5C,
|
||||
0x24, 0x40, 0x48, 0x83, 0xC4, 0x30, 0x5F, 0xC2, 0x00, 0x00
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
const char childProcessName[] = "child_processD.exe";
|
||||
#else
|
||||
const char childProcessName[] = "child_process.exe";
|
||||
#endif
|
||||
|
||||
uint64_t AlignTo2k(const uint64_t value)
|
||||
{
|
||||
return (value + (uint64_t)(2048 - 1)) & ~((uint64_t)(2048 - 1));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma warning (push, 0)
|
||||
int32_t main()
|
||||
{
|
||||
STARTUPINFOA startupInfo;
|
||||
PROCESS_INFORMATION processInfo;
|
||||
|
||||
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
|
||||
startupInfo.cb = sizeof(startupInfo);
|
||||
|
||||
ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
if (!CreateProcessA(childProcessName, "", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo))
|
||||
{
|
||||
printf("Failed to launch process. (Error code %" PRIu32 ")\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sleep(2000); // Let the child process live for a while.
|
||||
|
||||
void *pData = VirtualAllocEx(processInfo.hProcess, NULL, AlignTo2k(sizeof(shellcode)), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
||||
if (pData == NULL)
|
||||
{
|
||||
printf("Failed to allocate memory in child process. (Error code %" PRIu32 ")\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t bytesWritten = 0;
|
||||
|
||||
if (!WriteProcessMemory(processInfo.hProcess, pData, shellcode, sizeof(shellcode), &bytesWritten) || bytesWritten != sizeof(shellcode))
|
||||
{
|
||||
printf("Failed to write shellcode to child process memory. (Error code %" PRIu32 ")\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
DWORD threadId = 0;
|
||||
|
||||
if (!CreateRemoteThread(processInfo.hProcess, NULL, 0, (PTHREAD_START_ROUTINE)pData, NULL, 0, &threadId))
|
||||
{
|
||||
printf("Failed to create remote thread. (Error code %" PRIu32 ")\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
WaitForSingleObject(processInfo.hThread, INFINITE); // This should not be able to fail.
|
||||
|
||||
DWORD exitCode = 0;
|
||||
|
||||
if (!GetExitCodeProcess(processInfo.hProcess, &exitCode))
|
||||
{
|
||||
printf("Failed to retrieve exit code. (Error code %" PRIu32 ")\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Remote Thread terminated with exit code %" PRIu32 ".\n", exitCode);
|
||||
|
||||
CloseHandle(processInfo.hThread);
|
||||
CloseHandle(processInfo.hProcess);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#pragma warning (pop)
|
||||
Submodule
+1
Submodule premake added at 1e3e269a7d
@@ -0,0 +1,11 @@
|
||||
solution "shellcode_template"
|
||||
|
||||
editorintegration "On"
|
||||
platforms { "x64" }
|
||||
configurations { "Debug", "Release" }
|
||||
|
||||
dofile "shellcode_template/project.lua"
|
||||
|
||||
group "example"
|
||||
dofile "example/host_process/project.lua"
|
||||
dofile "example/child_process/project.lua"
|
||||
@@ -0,0 +1,77 @@
|
||||
public shellcode_template
|
||||
|
||||
.code
|
||||
shellcode_template:
|
||||
mov qword ptr [rsp+8], rbx
|
||||
push rdi
|
||||
sub rsp, 48
|
||||
mov rax, qword ptr gs:96
|
||||
xor edx, edx
|
||||
mov r9, 4711732171926431047
|
||||
mov rcx, qword ptr [rax+24]
|
||||
mov rax, qword ptr [rcx+32]
|
||||
mov rcx, qword ptr [rax]
|
||||
mov rax, qword ptr [rcx]
|
||||
mov rdi, qword ptr [rax+32]
|
||||
movsxd rax, dword ptr [rdi+60]
|
||||
mov r8d, dword ptr [rax+rdi+136]
|
||||
mov eax, dword ptr [r8+rdi+32]
|
||||
add rax, rdi
|
||||
movsxd rcx, dword ptr [rax]
|
||||
cmp qword ptr [rcx+rdi], r9
|
||||
je short _function_found
|
||||
nop
|
||||
nop
|
||||
|
||||
_check_next_function_name:
|
||||
movsxd rcx, dword ptr [rax+4]
|
||||
lea rax, qword ptr [rax+4]
|
||||
inc edx
|
||||
cmp qword ptr [rcx+rdi], r9
|
||||
jne short _check_next_function_name
|
||||
|
||||
_function_found:
|
||||
mov ecx, dword ptr [r8+rdi+28]
|
||||
mov rax, 8242266044863967052
|
||||
add rcx, rdi
|
||||
movsxd rdx, edx
|
||||
movsxd rbx, dword ptr [rcx+rdx*4]
|
||||
lea rdx, qword ptr 32[rsp]
|
||||
add rbx, rdi
|
||||
mov qword ptr 32[rsp], rax
|
||||
mov rcx, rdi
|
||||
mov qword ptr 32[rsp+8], 1098478177
|
||||
call rbx
|
||||
mov rcx, 7218762449265455989
|
||||
mov qword ptr 32[rsp+8], 27756
|
||||
mov qword ptr 32[rsp], rcx
|
||||
lea rcx, qword ptr 32[rsp]
|
||||
call rax
|
||||
mov rcx, 4784343847397451085
|
||||
mov qword ptr 32[rsp+8], 4290671
|
||||
mov qword ptr 32[rsp], rcx
|
||||
lea rdx, qword ptr 32[rsp]
|
||||
mov rcx, rax
|
||||
call rbx
|
||||
mov rcx, 7020021522101395784
|
||||
lea r8, qword ptr 32[rsp+15]
|
||||
mov qword ptr 32[rsp], rcx
|
||||
lea rdx, qword ptr 32[rsp]
|
||||
mov rcx, 9395827011843616
|
||||
xor r9d, r9d
|
||||
mov qword ptr 32[rsp+8], rcx
|
||||
xor ecx, ecx
|
||||
call rax
|
||||
mov rax, 7165071222045767749
|
||||
mov qword ptr 32[rsp+8], 7566181
|
||||
lea rdx, qword ptr 32[rsp]
|
||||
mov qword ptr 32[rsp], rax
|
||||
mov rcx, rdi
|
||||
call rbx
|
||||
mov ecx, -1
|
||||
call rax
|
||||
mov rbx, qword ptr [rsp+64]
|
||||
add rsp, 48
|
||||
pop rdi
|
||||
ret 0
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
ProjectName = "shellcode_template"
|
||||
project(ProjectName)
|
||||
|
||||
--Settings
|
||||
kind "ConsoleApp"
|
||||
language "C"
|
||||
flags { "StaticRuntime", "FatalWarnings" }
|
||||
|
||||
defines { "_CRT_SECURE_NO_WARNINGS" }
|
||||
|
||||
objdir "intermediate/obj"
|
||||
|
||||
files { "src/**.c", "src/**.cpp", "src/**.h", "src/**.inl", "src/**rc" }
|
||||
files { "project.lua" }
|
||||
|
||||
includedirs { "src" }
|
||||
|
||||
targetname(ProjectName)
|
||||
targetdir "../builds/bin"
|
||||
debugdir "../builds/bin"
|
||||
|
||||
filter { "configurations:Debug", "system:Windows" }
|
||||
ignoredefaultlibraries { "libcmt" }
|
||||
filter { }
|
||||
|
||||
filter {}
|
||||
configuration {}
|
||||
|
||||
warnings "Extra"
|
||||
|
||||
filter {"configurations:Release"}
|
||||
targetname "%{prj.name}"
|
||||
filter {"configurations:Debug"}
|
||||
targetname "%{prj.name}D"
|
||||
|
||||
filter { }
|
||||
flags { "NoPCH" }
|
||||
exceptionhandling "Off"
|
||||
rtti "Off"
|
||||
floatingpoint "Fast"
|
||||
|
||||
filter { "configurations:Debug*" }
|
||||
defines { "_DEBUG" }
|
||||
symbols "FastLink"
|
||||
|
||||
filter { "configurations:Release" }
|
||||
defines { "NDEBUG" }
|
||||
optimize "Speed"
|
||||
flags { "NoFramePointer", "NoBufferSecurityCheck", "NoIncrementalLink" }
|
||||
editandcontinue "Off"
|
||||
symbols "On"
|
||||
@@ -0,0 +1,123 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#pragma warning (push, 0)
|
||||
#include <winternl.h>
|
||||
|
||||
// This is the shellcode template function.
|
||||
// Modify it to make it fit your needs.
|
||||
//
|
||||
// Keep in mind:
|
||||
// Don't call any functions that you didn't load here (like CRT functions). If you want to split up your shellcode into multiple functions make sure to use `__declspec(forceinline)`.
|
||||
__declspec(noinline) void shellcode_template()
|
||||
{
|
||||
// Depending on your target you might have to 16-bit align stack pointer. Just place `and rsp, 0fffffffffffffff0h` after the initial `sub rsp XXXX` that will be generated at the start of the function.
|
||||
|
||||
// Load Process Environment Block.
|
||||
PEB *pProcessEnvironmentBlock = (PEB *)__readgsqword(0x60);
|
||||
|
||||
// `pProcessEnvironmentBlock->Ldr->InMemoryOrderModuleList` contains a double linked list.
|
||||
// `Flink` and `Blink` are the pointers to the next element.
|
||||
//
|
||||
// All Windows executables should have the following module order.
|
||||
// 1. The module of the current executable.
|
||||
// 2. `ntdll.dll` (`%windir%\System32\ntdll.dll`)
|
||||
// 3. `kernel32.dll` (`%windir%\System32\kernel32.dll`)
|
||||
//
|
||||
// ... followed by other modules.
|
||||
//
|
||||
// In order to get the `GetProcAddress` function we need to therefore get the third item (`Flink->Flink->Flink`).
|
||||
// We use the `CONTAINING_RECORD` macro to retrieve the associated table entry.
|
||||
LDR_DATA_TABLE_ENTRY *pKernel32TableEntry = CONTAINING_RECORD(pProcessEnvironmentBlock->Ldr->InMemoryOrderModuleList.Flink->Flink->Flink, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
|
||||
|
||||
// We've ended up at the base address of `kernel32.dll`.
|
||||
IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pKernel32TableEntry->DllBase;
|
||||
|
||||
// In order to get the exported functions we need to go to the NT PE header.
|
||||
IMAGE_NT_HEADERS *pNtHeader = (IMAGE_NT_HEADERS *)((uint8_t *)pDosHeader + pDosHeader->e_lfanew);
|
||||
|
||||
// From the NtHeader we can extract the virtual address of the export directory of this module.
|
||||
IMAGE_EXPORT_DIRECTORY *pExports = (IMAGE_EXPORT_DIRECTORY *)((uint8_t *)pDosHeader + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
|
||||
// The exports directory contains both a list of function _names_ of this module and the associated _addresses_ of the functions.
|
||||
const int32_t *pNameOffsets = (const int32_t *)((uint8_t *)pDosHeader + pExports->AddressOfNames);
|
||||
|
||||
// We will use this struct to store strings.
|
||||
// We are using a struct to make sure strings don't end up in another section of the executable where we wouldn't be able to address them in a different process.
|
||||
struct
|
||||
{
|
||||
uint64_t text0, text1;
|
||||
} x;
|
||||
|
||||
// We're now looking for the `GetProcAddress` function. Since there's no other function starting with `GetProcA` we'll just find that instead.
|
||||
x.text0 = 0x41636F7250746547; // `GetProcA`
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
// We're just extracting the first 8 bytes of the strings and compare them to `GetProcA`. We'll find it eventually.
|
||||
while (*(uint64_t *)((char *)pDosHeader + pNameOffsets[i]) != x.text0)
|
||||
++i;
|
||||
|
||||
// We have found the index of `GetProcAddress`.
|
||||
|
||||
// Not let's get the function offsets in order to retrieve the location of `GetProcAddress` in memory.
|
||||
const int32_t *pFunctionOffsets = (const int32_t *)((uint8_t *)pDosHeader + pExports->AddressOfFunctions);
|
||||
|
||||
typedef FARPROC(*GetProcAddressFunc)(HMODULE, const char *);
|
||||
GetProcAddressFunc pGetProcAddress = (GetProcAddressFunc)(const void *)((uint8_t *)pDosHeader + pFunctionOffsets[i]);
|
||||
|
||||
// Now that we've got `GetProcAddress`, let's use it to get `LoadLibraryA`.
|
||||
|
||||
// A HMODULE is just a pointer to the base address of a module.
|
||||
HMODULE kernel32Dll = (HMODULE)pDosHeader;
|
||||
|
||||
// Get `LoadLibraryA`.
|
||||
x.text0 = 0x7262694C64616F4C; // `LoadLibr`
|
||||
x.text1 = 0x0000000041797261; // `aryA\0\0\0\0`
|
||||
|
||||
typedef HMODULE(*LoadLibraryAFunc)(const char *);
|
||||
LoadLibraryAFunc pLoadLibraryA = (LoadLibraryAFunc)pGetProcAddress(kernel32Dll, (const char *)&x.text0);
|
||||
|
||||
// Load `user32.dll`.
|
||||
x.text0 = 0x642E323372657375; // `user32.d`
|
||||
x.text1 = 0x0000000000006C6C; // `ll\0\0\0\0\0\0`
|
||||
HMODULE user32Dll = pLoadLibraryA((const char *)&x.text0);
|
||||
|
||||
// Get `MessageBoxA`.
|
||||
x.text0 = 0x426567617373654D; // `MessageB`
|
||||
x.text1 = 0x000000000041786F; // `oxA\0\0\0\0\0`
|
||||
|
||||
typedef int32_t(*MessageBoxAFunc)(HWND, const char *, const char *, uint32_t);
|
||||
MessageBoxAFunc pMessageBoxA = (MessageBoxAFunc)pGetProcAddress(user32Dll, (const char *)&x.text0);
|
||||
|
||||
// Display a message box.
|
||||
x.text0 = 0x616C206174736148; // `Hasta la`
|
||||
x.text1 = 0x0021617473697620; // ` vbista!\0`
|
||||
|
||||
// MessageBoxA(NULL, "Hasta la vista", "", MB_OK);
|
||||
pMessageBoxA(NULL, (const char *)&x.text0, (const char *)&x.text1 + 7, MB_OK);
|
||||
|
||||
// Load `ExitProcess` from `kernel32.dll`.
|
||||
x.text0 = 0x636F725074697845; // `ExitProc`
|
||||
x.text1 = 0x0000000000737365; // `ess\0\0\0\0\0`
|
||||
|
||||
typedef void(*ExitProcessFunc)(uint32_t);
|
||||
ExitProcessFunc pExitProcess = (ExitProcessFunc)pGetProcAddress(kernel32Dll, (const char *)&x.text0);
|
||||
|
||||
// Kill the current process with exit code -1.
|
||||
pExitProcess((uint32_t)-1);
|
||||
}
|
||||
|
||||
#pragma warning (pop)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Just a main function to call your shell code.
|
||||
int main()
|
||||
{
|
||||
shellcode_template();
|
||||
|
||||
MessageBoxA(NULL, "Shell code has been executed.", "Success!", MB_OK); // in case your modified shell code function did not exit the current process.
|
||||
}
|
||||
Reference in New Issue
Block a user