首页
社区
课程
招聘
[原创] 腾讯游戏安全竞赛2022初赛
发表于: 2022-4-26 17:34 11562

[原创] 腾讯游戏安全竞赛2022初赛

2022-4-26 17:34
11562

Flag截图:

image-20220416191644068

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

image-20220416192002417

然后进入绘制主循环

image-20220416192027328

题目用的是shellcode来进行绘制的,这个shellcode看起来是编译器里提取出来的

代码将绘制所需的shellcode修复,并调用ZwAllocateVirtualMemory申请RWX内存写入shellcode

shellcode入口点为+0x650,传参swapchain指针

image-20220416192349203

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

image-20220416192517993

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

image-20220416192710386

image-20220416192735634

image-20220416192801616

提取出来Vertex Shader

Pixel Shader

由上面的CreateInputLayout函数调用参数得到顶点数据的结构为

纠正一下,因为顶点结构中没有设置alpha通道,所以透明度忽略,而下面代码设置顶点结构大小为28并不代表顶点有alpha通道
图片描述

创建顶点缓冲区

image-20220416192923873

+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)

dd111

利用该正方形的坐标来推出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编辑 ,原因: 加入绘制代码,纠正顶点结构
上传的附件:
收藏
免费 4
支持
分享
最新回复 (5)
雪    币: 8787
活跃值: (5798)
能力值: ( LV13,RANK:296 )
在线值:
发帖
回帖
粉丝
2
mark
2022-4-26 17:38
0
雪    币: 9792
活跃值: (1675)
能力值: ( LV12,RANK:261 )
在线值:
发帖
回帖
粉丝
3
mark
2022-4-26 18:56
0
雪    币: 14653
活跃值: (17749)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2022-4-26 23:47
0
雪    币: 8452
活跃值: (5046)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
5
mark
2022-4-27 12:33
0
雪    币: 886
活跃值: (2415)
能力值: ( LV4,RANK:52 )
在线值:
发帖
回帖
粉丝
6
mark
2022-5-8 21:42
0
游客
登录 | 注册 方可回帖
返回
//