//////////////////////////////////////////////////////////////////
// This is a loader for Skype which allows its usage with softice
// v2 : look 'n replace done
// tested with 1.2.0.48, 1.4.0.78, 2.0.0.69, 2.0.0.90
//////////////////////////////////////////////////////////////////

/* JUST FOR REFERENCE :

1.2.0.48 :
00D0BF72   74 1A          JE SHORT Skype_1_.00D0BF8E
00D0BF74   6A 00          PUSH 0
00D0BF76   68 2CCBD000    PUSH Skype_1_.00D0CB2C                   ; ASCII "Skype"
00D0BF7B   68 34CBD000    PUSH Skype_1_.00D0CB34                   ; ASCII "Skype is not compatible with system debuggers like SoftICE."
00D0BF80   6A 00          PUSH 0
00D0BF82   E8 A1C56FFF    CALL <JMP.&user32.MessageBoxA>
00D0BF87   6A 00          PUSH 0
00D0BF89   E8 92B96FFF    CALL <JMP.&kernel32.ExitProcess> 
00D0BF8E   B9 78CBD000    MOV ECX,Skype_1_.00D0CB78                ;  ASCII "Starting  .."

1.4.0.78 :
00B35DF6   74 1A            JE SHORT Skype_1_.00B35E12
00B35DF8   6A 00            PUSH 0
00B35DFA   68 3C6EB300      PUSH Skype_1_.00B36E3C                   ; ASCII "Skype"
00B35DFF   68 446EB300      PUSH Skype_1_.00B36E44                   ; ASCII "Skype is not compatible with system debuggers like SoftICE."
00B35E04   6A 00            PUSH 0
00B35E06   E8 052C8DFF      CALL <JMP.&user32.MessageBoxA>
00B35E0B   6A 00            PUSH 0
00B35E0D   E8 F61F8DFF      CALL <JMP.&kernel32.ExitProcess>
00B35E12   B9 886EB300      MOV ECX,Skype_1_.00B36E88                ; ASCII "Starting  .."

2.0.0.69 :
0xb6eb7a
00B76F41   74 1A            JE SHORT Skype_2_.00B76F5D
00B76F43   6A 00            PUSH 0
00B76F45   68 887FB700      PUSH Skype_2_.00B77F88                   ; ASCII "Skype"
00B76F4A   68 907FB700      PUSH Skype_2_.00B77F90                   ; ASCII "Skype is not compatible with system debuggers like SoftICE."
00B76F4F   6A 00            PUSH 0
00B76F51   E8 DA1B89FF      CALL <JMP.&user32.MessageBoxA>
00B76F56   6A 00            PUSH 0
00B76F58   E8 A30F89FF      CALL <JMP.&kernel32.ExitProcess>
00B76F5D   B9 D47FB700      MOV ECX,Skype_2_.00B77FD4                ; ASCII "Starting  .."

2.0.0.90 :
0xb74896
00B7CC69   74 1A            JE SHORT Skype.00B7CC85
00B7CC6B   6A 00            PUSH 0
00B7CC6D   68 B4DCB700      PUSH Skype.00B7DCB4                      ; ASCII "Skype"
00B7CC72   68 BCDCB700      PUSH Skype.00B7DCBC                      ; ASCII "Skype is not compatible with system debuggers like SoftICE."
00B7CC77   6A 00            PUSH 0
00B7CC79   E8 B2BE88FF      CALL <JMP.&user32.MessageBoxA>
00B7CC7E   6A 00            PUSH 0
00B7CC80   E8 7BB288FF      CALL <JMP.&kernel32.ExitProcess>
00B7CC85   B9 00DDB700      MOV ECX,Skype.00B7DD00                   ; ASCII "Starting  .."

search for :
74 1A 6A 00 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 6A 00 E8 ?? ?? ?? ?? 6A 00 E8 ?? ?? ?? ?? B9
replace with :
EB ...

Last version:

3.5.0.202 :
00585864   . 74 1C          JE SHORT Skype.00585882
00585866   . 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00585868   . FF35 5C1BE400  PUSH DWORD PTR DS:[E41B5C]               ; |Title = "Skype"
0058586E   . FF35 601BE400  PUSH DWORD PTR DS:[E41B60]               ; |Text = "Error: Skype is not compatible with debuggers like SoftICE .."
00585874   . 6A 00          PUSH 0                                   ; |hOwner = NULL
00585876   . E8 5D37E8FF    CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
0058587B   . 6A 01          PUSH 1                                   ; /ExitCode = 1
0058587D   . E8 5E2AE8FF    CALL <JMP.&kernel32.ExitProcess>         ; \ExitProcess
00585882   > BA 011E1600    MOV EDX,161E01                           ;  ASCII "13549.3.4"
00585887   . 81C2 175DCD00  ADD EDX,Skype.00CD5D17

search for :
74 1C 6A 00 FF 35 5C 1B E4 00 FF 35 60 1B E4 00
replace with :
EB ...
*/

#include <windows.h>
#include <stdio.h>

#define ERRORMSG(a) MessageBox(NULL, a, "Error", MB_ICONERROR|MB_OK);
#define BUFLEN 65535

//TCHAR searchData[30] = "\x74\x1A\x6A\x00\x68\xCC\xCC\xCC\xCC\x68\xCC\xCC\xCC\xCC\x6A\x00\xE8\xCC\xCC\xCC\xCC\x6A\x00\xE8\xCC\xCC\xCC\xCC\xB9";
//TCHAR searchData[17] = "\x74\x1C\x6A\x00\xFF\x35\xCC\xCC\xCC\xCC\xFF\x35\xCC\xCC\xCC\xCC";
TCHAR searchData[7] = "\x74\x1C\x6A\x00\xFF\x35";

//SIZE_T searchDataLen = 29;
//SIZE_T searchDataLen = 16;
SIZE_T searchDataLen = 6;
TCHAR wildcardByte = 0xCC; /* yeah, damn ugly, but who cares ? it works =) laziness is everything... */
TCHAR readBuffer[BUFLEN];
SIZE_T readLen;

int searchAndDestroy(void);

int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, int nCmdShow)
{
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	OFSTRUCT ofs;
	TCHAR buf[MAX_PATH] = "";
	TCHAR newByte = 0xEB;
	TCHAR origByte = 0x74;
	SIZE_T searchOffset = 0xA00000;
	SIZE_T searchOffsetStop = 0xF00000;
	SIZE_T patchOffset;

	(void)hinst;
	(void)hinstPrev;
	(void)lpCmdLine;
	(void)nCmdShow;
	
	GetModuleFileName(NULL, buf, MAX_PATH);
	buf[(strrchr(buf, '\\') - buf) + 1] = '\0';
	strcat(buf, "skype.exe");

	fprintf(stderr, "OpenFile... ");
	if (OpenFile(buf, &ofs, OF_EXIST) == HFILE_ERROR)
	{
		ERRORMSG("Skype.exe not found in current directory...exiting!")
		return 1;
	}
	fprintf(stderr, "OK\n");

	fprintf(stderr, "GetStartupInfo... ");
	GetStartupInfo(&si);
	fprintf(stderr, "OK\n");

	fprintf(stderr, "CreateProcess... ");
	printf("CreateProcess...\n");
	if (!CreateProcess((LPCSTR)buf,
		0,
		NULL,
		NULL,
		FALSE,
		CREATE_SUSPENDED,
		NULL,
		NULL,
		&si,
		&pi))
	{
		ERRORMSG("CreateProcess error...exiting!");
		return 1;
	}
	fprintf(stderr, "OK\n");
	
	while (searchOffset < searchOffsetStop) {
		fprintf(stderr, "ReadProcessMemory @ 0x%lx... ", searchOffset);
		if (!ReadProcessMemory(pi.hProcess, (LPCVOID)searchOffset, readBuffer, BUFLEN, &readLen))
		{
			ERRORMSG("ReadProcessMemory error...exiting!");
			return 1;
		}
		fprintf(stderr, "OK\n");
		fprintf(stderr, "Looking for data to patch... ");
		if ((patchOffset = searchAndDestroy()) < BUFLEN) {
			patchOffset += searchOffset - searchDataLen;
			fprintf(stderr, "FOUND at offset 0x%lx !\n", patchOffset);
			break;
		}
		else {
			fprintf(stderr, "not found\n");
		}
		searchOffset += BUFLEN - searchDataLen;
		patchOffset = 0;
	}
	
	if (!patchOffset) {
		ERRORMSG("Can't find patch offset, this is probably a too new version of Skype, sorry !");
		return 1;
	}

	fprintf(stderr, "WriteProcessMemory... ");
	if (!WriteProcessMemory(pi.hProcess, (LPVOID)patchOffset, &newByte, 1, NULL))
	{
		ERRORMSG("WriteProcessMemory error of newByte...exiting!");
		return 1;
	}
	fprintf(stderr, "OK\n");
	
	fprintf(stderr, "ResumeThread... ");
	if (!ResumeThread(pi.hThread))
	{
		ERRORMSG("ResumeThread error...exiting!");
	}
	fprintf(stderr, "OK\n");
	
	fprintf(stderr, "WaitForInputIdle... ");
	if (WaitForInputIdle(pi.hProcess, INFINITE))
	{
		ERRORMSG("WaitForInputIdle error...exiting!");
	}
	fprintf(stderr, "OK\n");
	
	fprintf(stderr, "WriteProcessMemory... ");
	if (!WriteProcessMemory(pi.hProcess, (LPVOID)patchOffset, &origByte, 1, NULL))
	{
		ERRORMSG("WriteProcessMemory error of origByte...exiting!");
	}
	fprintf(stderr, "OK\n");
	
	return 0;
}

int searchAndDestroy(void) {
	SIZE_T offset;
	SIZE_T searchOffset;

	for (offset = 0, searchOffset = 0; (offset < readLen) && (searchOffset < searchDataLen); offset++) {
		if ((readBuffer[offset] == searchData[searchOffset]) || (searchData[searchOffset] == wildcardByte)) { searchOffset++; }
		else { searchOffset = 0; }
	}

	return offset;
}

// EOF
