Flag截图:

题目先创建一个1920x1080的窗口,初始化d3d11创建swapchain

然后进入绘制主循环

题目用的是shellcode来进行绘制的,这个shellcode看起来是编译器里提取出来的
代码将绘制所需的shellcode修复,并调用ZwAllocateVirtualMemory申请RWX内存写入shellcode
shellcode入口点为+0x650,传参swapchain指针

进入shellcode后,先拿ID3D11Device指针和ID3D11DeviceContext指针

初始化d3d11参数,编译所需的Shader,设置顶点格式,设置Vertex Shader和Pixel Shader



提取出来Vertex Shader
Pixel Shader
由上面的CreateInputLayout函数调用参数得到顶点数据的结构为
纠正一下,因为顶点结构中没有设置alpha通道,所以透明度忽略,而下面代码设置顶点结构大小为28并不代表顶点有alpha通道

创建顶点缓冲区

+420是读取内存中的"ACE"文字顶点数据然后调用+0将正方形画到directx11缓冲区里
题目的目标是画出flag,所以不管这些顶点数据,定位到画正方形部分逻辑
经过反编译后的+0
逻辑一目了然,接下来就是hook+420来实现绘制flag图形
用CreateProcess的CREATE_SUSPENDED标志在exe入口点加载之前注入dll
修改shellcode内容,先jmp过去
因为绘制是单线程的,所以可以任意的使用全局变量
先把临时将返回地址保存在全局变量g_lr里,然后将栈中返回地址修改为后半段,跳到myrender_saver函数中
把本次调用的参数保存到全局变量里,然后赋值g_resume_ip为exe调用ZwAllocateVirtualMemory返回的内存
返回之后需要保存全部寄存器环境调用自己的绘制函数,调用自己的绘制函数之前还需要强制平衡堆栈
最后调用myrender_draw函数,正式开始绘制flag流程
因为题目没初始化shader的 WVP matrix,所以绘制的坐标系是d3d11的左手坐标系,(0,0,0)就是屏幕的中心,摄像机坐标在(0,0,0),所以整个1920x1080的屏幕最左边x坐标是-1,最右边x坐标是1,最顶端y坐标是1,最底端y坐标是-1
通过调试起来的数据得知一个正方形在dx坐标系里表示高度为0.09259259,宽度为0.05208334,横向间隔为0.01041667,纵向间隔为0.01851857
该正方形左上坐标为(-0.57347451,0.46388888)

利用该正方形的坐标来推出flag的各个位置来绘制
solved
cbuffer ConstantBuffer : register(b0){matrix World;matrix View;matrix Projection;}
struct VS_OUTPUT{float4 Pos : SV_POSITION;float4 Color : COLOR0;};
VS_OUTPUT VS(float4 Pos : POSITION, float4 Color : COLOR)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul(Pos, World);
output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection);
output.Color = Color;
return output;
}
float4 PS(VS_OUTPUT input) : SV_Target{return input.Color;}
cbuffer ConstantBuffer : register(b0){matrix World;matrix View;matrix Projection;}
struct VS_OUTPUT{float4 Pos : SV_POSITION;float4 Color : COLOR0;};
VS_OUTPUT VS(float4 Pos : POSITION, float4 Color : COLOR)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul(Pos, World);
output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection);
output.Color = Color;
return output;
}
float4 PS(VS_OUTPUT input) : SV_Target{return input.Color;}
struct VSOut{float4 Col : COLOR;float4 Pos : SV_POSITION;};
VSOut VS(float4 Col : COLOR, float4 Pos : POSITION)
{
VSOut Output;
Output.Pos = Pos;
Output.Col = Col;
return Output;
}
float4 PS(float4 Col : COLOR) : SV_TARGET{return Col;}
struct VSOut{float4 Col : COLOR;float4 Pos : SV_POSITION;};
VSOut VS(float4 Col : COLOR, float4 Pos : POSITION)
{
VSOut Output;
Output.Pos = Pos;
Output.Col = Col;
return Output;
}
float4 PS(float4 Col : COLOR) : SV_TARGET{return Col;}
struct Vertex
{
float x,y,z;
float r,g,b;
}
struct Vertex
{
float x,y,z;
float r,g,b;
}
__int64 __fastcall drawbox(int a1, int a2, int a3, int a4, __int64 a5, ID3D11DeviceContext *ctx, __int64 buffer, __int64 layout, __int64 vs, __int64 ps)
{
__int64 v10; // rdi
ID3D11DeviceContext *ctx_1; // r14
unsigned int rgba; // ebx
int v17; // ecx
float y_top_off; // xmm9_4
float y_bottom_off; // xmm11_4
float x_left_off; // xmm7_4
float x_right_off; // xmm10_4
Vertex *vtx_buffer; // rcx
float f255; // xmm0_4
float mid; // xmm8_4
float x_left; // xmm6_4
float y_top; // xmm3_4
float x_right; // xmm1_4
float y_bottom; // xmm8_4
float v29; // xmm7_4
float v30; // xmm5_4
float v31; // xmm4_4
float v32; // xmm2_4
ID3D11DeviceContextVtbl *v33; // rax
D3D11_MAPPED_SUBRESOURCE v35; // [rsp+20h] [rbp-C8h] BYREF
char v36[8]; // [rsp+30h] [rbp-B8h] BYREF
float v37; // [rsp+38h] [rbp-B0h]
float v38; // [rsp+3Ch] [rbp-ACh]
__int64 v39; // [rsp+C8h] [rbp-20h]
int v40; // [rsp+F8h] [rbp+10h] BYREF
int v41; // [rsp+100h] [rbp+18h] BYREF
__int64 v42; // [rsp+108h] [rbp+20h] BYREF
v39 = v10;
ctx_1 = ctx;
v40 = 1;
rgba = a5 + (a3 ^ (a1 + a2)) % 256 - a4 % 256;
((void (__fastcall *)(ID3D11DeviceContext *, int *, char *))ctx->lpVtbl->RSGetViewports)(ctx, &v40, v36);
v17 = (a3 ^ (a2 * a1)) % 256 - (a4 >> 8) % 256;
y_top_off = (float)(v38 - (float)(2 * (v17 + a2) - 1)) / v38;
y_bottom_off = (float)(v38 - (float)(2 * a2 + 99)) / v38;
x_left_off = (float)((float)(2 * (v17 + a1) - 1) - v37) / v37;
x_right_off = (float)((float)(2 * a1 + 99) - v37) / v37;
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD, __int64, _DWORD, D3D11_MAPPED_SUBRESOURCE *))ctx_1->lpVtbl->Map)(
ctx_1,
buffer,
0i64,
4i64,
0,
&v35);
vtx_buffer = (Vertex *)v35.pData;
LODWORD(a5) = 0x437F0000; // 255.0
*((float *)v35.pData + 2) = (float)0;
f255 = *(float *)&a5;
mid = (float)((a3 ^ (a2 + a1 * (a2 + 1))) % 256 - (a4 >> 16) % 256);
x_left = mid + x_left_off;
y_top = mid + y_top_off;
vtx_buffer->x = mid + x_left_off;
x_right = mid + x_right_off;
vtx_buffer->y = mid + y_top_off;
y_bottom = mid + y_bottom_off;
v29 = (float)BYTE2(rgba) / f255;
v30 = (float)(unsigned __int8)(rgba >> 12) / f255;
v31 = (float)(unsigned __int8)rgba / f255;
vtx_buffer->r = v29;
vtx_buffer->g = v30;
v32 = (float)HIBYTE(rgba) / f255;
vtx_buffer->a = v32;
vtx_buffer[1].z = (float)0;
vtx_buffer[1].a = v32;
vtx_buffer[2].z = (float)0;
vtx_buffer[2].a = v32;
vtx_buffer[3].a = v32;
vtx_buffer->b = v31;
vtx_buffer[1].x = x_right;
vtx_buffer[1].y = y_top;
vtx_buffer[1].r = v29;
vtx_buffer[1].g = v30;
vtx_buffer[1].b = v31;
vtx_buffer[2].x = x_left;
vtx_buffer[2].y = y_bottom;
vtx_buffer[2].r = v29;
vtx_buffer[2].g = v30;
vtx_buffer[2].b = v31;
vtx_buffer[3].x = x_right;
vtx_buffer[3].y = y_bottom;
vtx_buffer[3].r = v29;
vtx_buffer[3].g = v30;
vtx_buffer[3].b = v31;
vtx_buffer[3].z = (float)0;
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD))ctx_1->lpVtbl->Unmap)(ctx_1, buffer, 0i64);
v33 = ctx_1->lpVtbl;
LODWORD(v42) = 28;
v41 = 0;
((void (__fastcall *)(ID3D11DeviceContext *, _QWORD, __int64, __int64 *, __int64 *, int *))v33->IASetVertexBuffers)(
ctx_1,
0i64,
1i64,
&buffer,
&v42,
&v41);
((void (__fastcall *)(ID3D11DeviceContext *, __int64))ctx_1->lpVtbl->IASetPrimitiveTopology)(ctx_1, 5i64);// D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
((void (__fastcall *)(ID3D11DeviceContext *, __int64))ctx_1->lpVtbl->IASetInputLayout)(ctx_1, layout);
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD, _QWORD))ctx_1->lpVtbl->VSSetShader)(
ctx_1,
vs,
0i64,
0i64);
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD, _QWORD))ctx_1->lpVtbl->PSSetShader)(
ctx_1,
ps,
0i64,
0i64);
((void (__fastcall *)(ID3D11DeviceContext *, _QWORD, _QWORD, _QWORD))ctx_1->lpVtbl->GSSetShader)(
ctx_1,
0i64,
0i64,
0i64);
return ((__int64 (__fastcall *)(ID3D11DeviceContext *, __int64))ctx_1->lpVtbl->Draw)(ctx_1, 4i64);
}
__int64 __fastcall drawbox(int a1, int a2, int a3, int a4, __int64 a5, ID3D11DeviceContext *ctx, __int64 buffer, __int64 layout, __int64 vs, __int64 ps)
{
__int64 v10; // rdi
ID3D11DeviceContext *ctx_1; // r14
unsigned int rgba; // ebx
int v17; // ecx
float y_top_off; // xmm9_4
float y_bottom_off; // xmm11_4
float x_left_off; // xmm7_4
float x_right_off; // xmm10_4
Vertex *vtx_buffer; // rcx
float f255; // xmm0_4
float mid; // xmm8_4
float x_left; // xmm6_4
float y_top; // xmm3_4
float x_right; // xmm1_4
float y_bottom; // xmm8_4
float v29; // xmm7_4
float v30; // xmm5_4
float v31; // xmm4_4
float v32; // xmm2_4
ID3D11DeviceContextVtbl *v33; // rax
D3D11_MAPPED_SUBRESOURCE v35; // [rsp+20h] [rbp-C8h] BYREF
char v36[8]; // [rsp+30h] [rbp-B8h] BYREF
float v37; // [rsp+38h] [rbp-B0h]
float v38; // [rsp+3Ch] [rbp-ACh]
__int64 v39; // [rsp+C8h] [rbp-20h]
int v40; // [rsp+F8h] [rbp+10h] BYREF
int v41; // [rsp+100h] [rbp+18h] BYREF
__int64 v42; // [rsp+108h] [rbp+20h] BYREF
v39 = v10;
ctx_1 = ctx;
v40 = 1;
rgba = a5 + (a3 ^ (a1 + a2)) % 256 - a4 % 256;
((void (__fastcall *)(ID3D11DeviceContext *, int *, char *))ctx->lpVtbl->RSGetViewports)(ctx, &v40, v36);
v17 = (a3 ^ (a2 * a1)) % 256 - (a4 >> 8) % 256;
y_top_off = (float)(v38 - (float)(2 * (v17 + a2) - 1)) / v38;
y_bottom_off = (float)(v38 - (float)(2 * a2 + 99)) / v38;
x_left_off = (float)((float)(2 * (v17 + a1) - 1) - v37) / v37;
x_right_off = (float)((float)(2 * a1 + 99) - v37) / v37;
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD, __int64, _DWORD, D3D11_MAPPED_SUBRESOURCE *))ctx_1->lpVtbl->Map)(
ctx_1,
buffer,
0i64,
4i64,
0,
&v35);
vtx_buffer = (Vertex *)v35.pData;
LODWORD(a5) = 0x437F0000; // 255.0
*((float *)v35.pData + 2) = (float)0;
f255 = *(float *)&a5;
mid = (float)((a3 ^ (a2 + a1 * (a2 + 1))) % 256 - (a4 >> 16) % 256);
x_left = mid + x_left_off;
y_top = mid + y_top_off;
vtx_buffer->x = mid + x_left_off;
x_right = mid + x_right_off;
vtx_buffer->y = mid + y_top_off;
y_bottom = mid + y_bottom_off;
v29 = (float)BYTE2(rgba) / f255;
v30 = (float)(unsigned __int8)(rgba >> 12) / f255;
v31 = (float)(unsigned __int8)rgba / f255;
vtx_buffer->r = v29;
vtx_buffer->g = v30;
v32 = (float)HIBYTE(rgba) / f255;
vtx_buffer->a = v32;
vtx_buffer[1].z = (float)0;
vtx_buffer[1].a = v32;
vtx_buffer[2].z = (float)0;
vtx_buffer[2].a = v32;
vtx_buffer[3].a = v32;
vtx_buffer->b = v31;
vtx_buffer[1].x = x_right;
vtx_buffer[1].y = y_top;
vtx_buffer[1].r = v29;
vtx_buffer[1].g = v30;
vtx_buffer[1].b = v31;
vtx_buffer[2].x = x_left;
vtx_buffer[2].y = y_bottom;
vtx_buffer[2].r = v29;
vtx_buffer[2].g = v30;
vtx_buffer[2].b = v31;
vtx_buffer[3].x = x_right;
vtx_buffer[3].y = y_bottom;
vtx_buffer[3].r = v29;
vtx_buffer[3].g = v30;
vtx_buffer[3].b = v31;
vtx_buffer[3].z = (float)0;
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD))ctx_1->lpVtbl->Unmap)(ctx_1, buffer, 0i64);
v33 = ctx_1->lpVtbl;
LODWORD(v42) = 28;
v41 = 0;
((void (__fastcall *)(ID3D11DeviceContext *, _QWORD, __int64, __int64 *, __int64 *, int *))v33->IASetVertexBuffers)(
ctx_1,
0i64,
1i64,
&buffer,
&v42,
&v41);
((void (__fastcall *)(ID3D11DeviceContext *, __int64))ctx_1->lpVtbl->IASetPrimitiveTopology)(ctx_1, 5i64);// D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
((void (__fastcall *)(ID3D11DeviceContext *, __int64))ctx_1->lpVtbl->IASetInputLayout)(ctx_1, layout);
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD, _QWORD))ctx_1->lpVtbl->VSSetShader)(
ctx_1,
vs,
0i64,
0i64);
((void (__fastcall *)(ID3D11DeviceContext *, __int64, _QWORD, _QWORD))ctx_1->lpVtbl->PSSetShader)(
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-4-26 21:56
被cslime编辑
,原因: 加入绘制代码,纠正顶点结构