1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-01-20 20:37:27 +01:00

Landing #5, Meatballs' fixes for cdecl in railgun

This commit is contained in:
James Lee 2013-04-04 20:40:11 -05:00
commit 4131c3bb4e
2 changed files with 91 additions and 1 deletions

View File

@ -207,6 +207,7 @@ DWORD railgun_call( RAILGUN_INPUT * pInput, RAILGUN_OUTPUT * pOutput )
__try
{
#ifdef _WIN64
switch( dwStackSizeInElements )
{
case 0: pOutput->qwReturnValue = function( 00 )(); break;
@ -242,6 +243,83 @@ DWORD railgun_call( RAILGUN_INPUT * pInput, RAILGUN_OUTPUT * pOutput )
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
#else
dprintf( "[RAILGUN] railgun_call: Calling convention %s", pInput->cpCallConv);
if ( strcmp(pInput->cpCallConv, "cdecl") == 0 )
{
switch( dwStackSizeInElements )
{
case 0: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)(); break;
case 1: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0) ); break;
case 2: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1) ); break;
case 3: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2) ); break;
case 4: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3) );break;
case 5: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4) );break;
case 6: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5) );break;
case 7: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6) );break;
case 8: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7) );break;
case 9: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8) );break;
case 10: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9) );break;
case 11: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10) );break;
case 12: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11) );break;
case 13: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12) );break;
case 14: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13) );break;
case 15: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14) );break;
case 16: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15) );break;
case 17: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16) );break;
case 18: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17) );break;
case 19: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18) );break;
case 20: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19) );break;
case 21: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20) );break;
case 22: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21) );break;
case 23: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21), p(22) );break;
case 24: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21), p(22), p(23) );break;
case 25: pOutput->qwReturnValue = ((CDECL_FUNC)pFuncAddr)( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21), p(22), p(23), p(24) );break;
default:
dprintf( "[RAILGUN] railgun_call: Can't call function: dwStackSizeInElements (%d) is > 25", dwStackSizeInElements );
pOutput->qwReturnValue = -1;
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
} else { // STDCALL
switch( dwStackSizeInElements )
{
case 0: pOutput->qwReturnValue = function( 00 )(); break;
case 1: pOutput->qwReturnValue = function( 01 )( p(0) ); break;
case 2: pOutput->qwReturnValue = function( 02 )( p(0), p(1) ); break;
case 3: pOutput->qwReturnValue = function( 03 )( p(0), p(1), p(2) ); break;
case 4: pOutput->qwReturnValue = function( 04 )( p(0), p(1), p(2), p(3) );break;
case 5: pOutput->qwReturnValue = function( 05 )( p(0), p(1), p(2), p(3), p(4) );break;
case 6: pOutput->qwReturnValue = function( 06 )( p(0), p(1), p(2), p(3), p(4), p(5) );break;
case 7: pOutput->qwReturnValue = function( 07 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6) );break;
case 8: pOutput->qwReturnValue = function( 08 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7) );break;
case 9: pOutput->qwReturnValue = function( 09 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8) );break;
case 10: pOutput->qwReturnValue = function( 10 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9) );break;
case 11: pOutput->qwReturnValue = function( 11 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10) );break;
case 12: pOutput->qwReturnValue = function( 12 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11) );break;
case 13: pOutput->qwReturnValue = function( 13 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12) );break;
case 14: pOutput->qwReturnValue = function( 14 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13) );break;
case 15: pOutput->qwReturnValue = function( 15 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14) );break;
case 16: pOutput->qwReturnValue = function( 16 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15) );break;
case 17: pOutput->qwReturnValue = function( 17 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16) );break;
case 18: pOutput->qwReturnValue = function( 18 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17) );break;
case 19: pOutput->qwReturnValue = function( 19 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18) );break;
case 20: pOutput->qwReturnValue = function( 20 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19) );break;
case 21: pOutput->qwReturnValue = function( 21 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20) );break;
case 22: pOutput->qwReturnValue = function( 22 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21) );break;
case 23: pOutput->qwReturnValue = function( 23 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21), p(22) );break;
case 24: pOutput->qwReturnValue = function( 24 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21), p(22), p(23) );break;
case 25: pOutput->qwReturnValue = function( 25 )( p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), p(12), p(13), p(14), p(15), p(16), p(17), p(18), p(19), p(20), p(21), p(22), p(23), p(24) );break;
default:
dprintf( "[RAILGUN] railgun_call: Can't call function: dwStackSizeInElements (%d) is > 25", dwStackSizeInElements );
pOutput->qwReturnValue = -1;
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
}
#endif
}
__except( EXCEPTION_EXECUTE_HANDLER )
@ -426,6 +504,11 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
if( !rInput.cpFuncName )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_FUNCNAME", ERROR_INVALID_PARAMETER );
// Get cpCallConv
rInput.cpCallConv = packet_get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_CALLCONV );
if( !rInput.cpCallConv )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_CALLCONV", ERROR_INVALID_PARAMETER );
// get the pStack-description (1 ULONG_PTR description, 1 ULONG_PTR data)
if( packet_get_tlv( pPacket, TLV_TYPE_RAILGUN_STACKBLOB, &rInput.pStackDescriptorTlv ) != ERROR_SUCCESS)
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_STACKBLOB", ERROR_INVALID_PARAMETER );

View File

@ -18,11 +18,13 @@
#define TLV_TYPE_RAILGUN_MEM_ADDRESS MAKE_CUSTOM_TLV( TLV_META_TYPE_QWORD, TLV_TYPE_EXTENSION_RAILGUN, TLV_EXTENSIONS + 12 )
#define TLV_TYPE_RAILGUN_MEM_DATA MAKE_CUSTOM_TLV( TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_RAILGUN, TLV_EXTENSIONS + 13 )
#define TLV_TYPE_RAILGUN_MEM_LENGTH MAKE_CUSTOM_TLV( TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_RAILGUN, TLV_EXTENSIONS + 14 )
#define TLV_TYPE_RAILGUN_CALLCONV MAKE_CUSTOM_TLV( TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_RAILGUN, TLV_EXTENSIONS + 15 )
typedef struct _RAILGUN_INPUT
{
const char * cpDllName;
const char * cpFuncName;
const char * cpCallConv;
BYTE * pBufferIN;
BYTE * pBufferINOUT;
ULONG_PTR dwBufferSizeIN;
@ -71,9 +73,14 @@ typedef ULONG_PTR (__stdcall * STDCALL_FUNC_23)( ULONG_PTR, ULONG_PTR, ULONG_PTR
typedef ULONG_PTR (__stdcall * STDCALL_FUNC_24)( ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR );
typedef ULONG_PTR (__stdcall * STDCALL_FUNC_25)( ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR );
typedef ULONG_PTR (__cdecl * CDECL_FUNC)( VOID );
typedef ULONG_PTR (__cdecl * CDECL_FUNC)( ULONG_PTR );
typedef ULONG_PTR (__cdecl * CDECL_FUNC)( ULONG_PTR, ... );
DWORD request_railgun_api_multi( Remote * remote, Packet * packet );
DWORD request_railgun_api( Remote * pRemote, Packet * pPacket );
DWORD request_railgun_memread( Remote * pRemote, Packet * pPacket );
DWORD request_railgun_memwrite( Remote * pRemote, Packet * pPacket );
#endif
#endif