int
counter
=
0
;
+
(UINT32)(((const UINT8
*
)(d))[
0
]) )
SIZE_T StringLengthA(LPCSTR String)
{
LPCSTR String2;
for
(String2
=
String;
*
String2;
+
+
String2);
return
(String2
-
String);
}
UINT32 HashStringSuperFastHashA(PCHAR String)
{
INT
Length
=
StringLengthA(String);
/
/
printf(
"[+] Len=%d\n"
, Length);
UINT32
Hash
=
Length;
INT
Tmp
=
0
;
INT
Rem
=
Length &
3
;
Length >>
=
2
;
for
(; Length >
0
; Length
-
-
)
{
Hash
+
=
Get16Bits(String);
Tmp
=
(Get16Bits(String
+
2
) <<
11
) ^
Hash
;
Hash
=
(
Hash
<<
16
) ^ Tmp;
String
+
=
2
*
sizeof(UINT16);
Hash
+
=
Hash
>>
11
;
}
switch (Rem)
{
case
3
:
{
Hash
+
=
Get16Bits(String);
Hash
^
=
Hash
<<
16
;
Hash
^
=
((UCHAR)String[sizeof(UINT16)]) <<
18
;
Hash
+
=
Hash
>>
11
;
break
;
}
case
2
:
{
Hash
+
=
Get16Bits(String);
Hash
^
=
Hash
<<
11
;
Hash
^
=
Hash
>>
17
;
break
;
}
case
1
:
{
Hash
+
=
(UCHAR)
*
String;
Hash
^
=
Hash
<<
10
;
Hash
+
=
Hash
>>
1
;
}
}
Hash
^
=
Hash
<<
3
;
Hash
+
=
Hash
>>
5
;
Hash
^
=
Hash
<<
4
;
Hash
+
=
Hash
>>
17
;
Hash
^
=
Hash
<<
25
;
Hash
+
=
Hash
>>
6
;
return
Hash
;
}
static void HandleException(
const DEBUG_EVENT& ev,
HANDLE ph,
HANDLE th) {
CONTEXT ctx{};
ctx.ContextFlags
=
CONTEXT_CONTROL | CONTEXT_INTEGER;
BOOL
ret
=
GetThreadContext(th, &ctx);
assert
(ret);
BYTE buf[
2
]{};
BYTE nops[]
=
{
0x90
,
0x90
};
BYTE ret_nop[]
=
{
0xc3
,
0x90
};
SIZE_T actually_read
=
0
;
ret
=
ReadProcessMemory(
ph, (void
*
)ctx.Rip, buf,
2
, &actually_read);
assert
(ret);
char str_x[
2
]
=
{
0
};
if
(buf[
0
]
=
=
0x0f
&& buf[
1
]
=
=
0x0b
) {
/
/
printf(
"UD2 Found\n"
);
str_x[
0
]
=
ctx.R12
%
256
;
UINT32
hash
=
HashStringSuperFastHashA(str_x);
/
/
printf(
"%d , %p , %c\n"
, ctx.R13, ctx.R11, str_x[
0
]);
if
(
hash
=
=
ctx.R11 && ctx.R13
=
=
1
)
{
/
/
printf(
"%c,%d\n"
, ctx.R12
%
256
, counter);
counter
+
+
;
}
if
(counter
=
=
24
)
{
printf(
"Correct Flag :)\n"
);
ret
=
WriteProcessMemory(
ph, (void
*
)ctx.Rip, ret_nop,
2
, &actually_read);
SetThreadContext(th, &ctx);
}
if
(counter !
=
24
)
{
ret
=
WriteProcessMemory(
ph, (void
*
)ctx.Rip, nops,
2
, &actually_read);
SetThreadContext(th, &ctx);
}
}
}
int
Debugger(char
*
file_name) {
/
/
puts(
"Debugger"
);
_putenv(
"ix221iscc221=1"
);
STARTUPINFO si{};
si.cb
=
sizeof(si);
PROCESS_INFORMATION pi{};
BOOL
ret
=
CreateProcess(
file_name, NULL,
NULL, NULL,
FALSE,
DEBUG_PROCESS,
NULL,
NULL,
&si, &pi);
DEBUG_EVENT ev;
std::unordered_map<DWORD, HANDLE> threads;
threads[pi.dwThreadId]
=
pi.hThread;
bool
the_end
=
false;
while
(!the_end) {
ret
=
WaitForDebugEvent(&ev, INFINITE);
if
(!ret) {
printf(
"Weird failed: %u\n"
, GetLastError());
return
1
;
}
switch (ev.dwDebugEventCode) {
case EXCEPTION_DEBUG_EVENT:
HandleException(ev, pi.hProcess, threads[ev.dwThreadId]);
break
;
case EXIT_PROCESS_DEBUG_EVENT:
the_end
=
true;
break
;
case CREATE_THREAD_DEBUG_EVENT:
threads[ev.dwThreadId]
=
ev.u.CreateThread.hThread;
break
;
case EXIT_THREAD_DEBUG_EVENT:
CloseHandle(threads[ev.dwThreadId]);
threads.erase(ev.dwThreadId);
break
;
case CREATE_PROCESS_DEBUG_EVENT:
CloseHandle(ev.u.CreateProcessInfo.hFile);
CloseHandle(ev.u.CreateProcessInfo.hProcess);
CloseHandle(ev.u.CreateProcessInfo.hThread);
break
;
case LOAD_DLL_DEBUG_EVENT:
case UNLOAD_DLL_DEBUG_EVENT:
break
;
default:
printf(
"Weird: %u\n"
, ev.dwDebugEventCode);
break
;
}
ContinueDebugEvent(
ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return
0
;
}
int
Debuggee() {
unsigned char
input
[
25
]
=
{
0
};
printf(
"Enter The Flag:\n"
);
scanf(
"%s"
, &
input
);
unsigned char data[]
=
{
0x44
,
0x49
,
0xC1
,
0xCB
,
0x0D
,
0x49
,
0xBD
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x0F
,
0x0B
,
0x44
,
0x8A
,
0x61
, 。。。。。 };
/
/
省略
/
/
;
long
size
=
sizeof(data);
PVOID image;
image
=
VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(image, data, size);
void (
*
foo)(unsigned char
*
)
=
(void(
*
)(unsigned char
*
))image;
foo(
input
);
return
0
;
}
int
main(
int
argc, char
*
*
argv) {
if
(getenv(
"ix221iscc221"
)
=
=
nullptr) {
return
Debugger(argv[
0
]);
}
else
{
return
Debuggee();
}
}