OutputDebugString.txt


/*
* pseudocode for OutputDebugString
*
* from KERNEL32.DLL ver 5.0.2195.6794
*
* Reverse engineered by Steve Friedl ([email protected])
*/
void OutputDebugStringA(LPTSTR *lpString)
{
DBWIN_buffer *pDBBuffer = 0;
HANDLE hFileMap = 0;
HANDLE hBufferEvent = 0;
HANDLE hDataEvent = 0;

// if we can't make or acquire the mutex, we're done

if ( hDbwinMutex == 0 )
hDbwinMutex = setup_mutex();

if ( hDbwinMutex == 0) return;

(void) WaitForSingleObject(hDbwinMutex, INFINITE);


hFileMap = OpenFileMapping(FILE_MAP_WRITE, FALSE, "DBWIN_BUFFER");

pDBBuffer = (DBWIN_buffer *) MapViewOfFile(
hFileMap,
FILE_MAP_READ|FILE_MAP_WRITE,
0, // file offset high
0, // file offset low
0 ); // # of bytes to map (entire file)

hBufferEvent = OpenEvent( SYNCHRONIZE, FALSE, "DBWIN_BUFFER_READY");
hDataEvent = OpenEvent( EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");

const char *p = lpString;
int len = strlen(lpString);

while ( len > 0 )
{
if ( WaitForSingleObject(hBufferEvent, 10*1000) != WAIT_OBJECT_0 )
{
/* ERROR: give up */
break;
}

// populate the shared memory segment. The string
// is limited to 4k or so.
pBuffer->dwProcessId = GetCurrentProcessId();

int n = min(len, sizeof(pBuffer->data)-1);

memcpy(pBuffer->data, p, n);
pBuffer->data[n] = '/0';

len -= n;
p += n;

SetEvent(hDataEvent);
}

// cleanup after ourselves
CloseHandle(hBufferEvent);
CloseHandle(hDataEvent);
UnmapViewOfFile(pDBBuffer);
CloseHandle(hFileMap);
}

HANDLE setup_mutex(void)
{
SID_IDENTIFIER_AUTHORITY SIAWindowsNT = SECURITY_NT_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIAWorld = SECURITY_WORLD_SID_AUTHORITY;

SID *pSidSYSTEM = 0, //
*pSidAdmins = 0,
*pSidEveryone = 0;

AllocateAndInitializeSid(&SIAWindowsNT,
1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&pSidSYSTEM);

AllocateAndInitializeSid(&SIAWindowsNT,
2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSidAdmins);

AllocateAndInitializeSid(&SIAWorld,
1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pSidEveryone);

const DWORD dwACLSize = GetLengthSid(pSidSYSTEM)
+ GetLengthSig(pSidAdmins)
+ GetLengthSig(pSidEveryone)
+ 32;

ACL *pACL = GlobalAlloc( 0, dwACLSize );

InitializeAcl(pACL, dwACLsize, ACL_REVISION );

AddAccessAllowedAce(pACL,
ACL_REVISION,
SYNCHRONIZE | READ_CONTROL | MUTEX_QUERY_STATE,
pSidEveryone);

AddAccessAllowedAce(pACL,
ACL_REVISION,
MUTEX_ALL_ACCESS,
pSidSYSTEM);

AddAccessAllowedAce(pACL,
ACL_REVISION,
MUTEX_ALL_ACCESS,
pSidAdmins);

SECURITY_DESCRIPTOR sd;

InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

SetSecurityDescriptorDacl(&sd, TRUE, pACL, FALSE);

SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof sa);

sa.bInheritHandle = FALSE;
sa.nLength = sizeof sa;
sa.lpSecurityDescriptor = &sd;

HANDLE hMutex = CreateMutex(&sa, FALSE, "DBWinMutex");

FreeSid(pSidAdmins);
FreeSid(pSidSYSTEM);
FreeSid(pSidEveryone);
GlobalFree(pACL);

return hMutex;
}