From e69b7d8738ee68615f6358e0d3f9ebbe12e399b0 Mon Sep 17 00:00:00 2001 From: Cc28257 <1109692332@qq.com> Date: Sat, 26 Sep 2020 17:24:19 +0800 Subject: [PATCH] fix asm name --- CcMainDll/.vs/CcMainDll/v15/.suo | Bin 128512 -> 126976 bytes .../Release/CcMainDll.Build.CppClean.log | 39 -- CcMainDll/CcMainDll/dllmain.cpp | 345 +++++++++--------- bin/server/CcMainDll.dll | Bin 226304 -> 226304 bytes 4 files changed, 168 insertions(+), 216 deletions(-) diff --git a/CcMainDll/.vs/CcMainDll/v15/.suo b/CcMainDll/.vs/CcMainDll/v15/.suo index 2de3211f6ba6de0d18d26ee01ce66f88874b71a9..93fa31de61ce49a3f67622098af1352f19755288 100644 GIT binary patch delta 5824 zcmd^@33Qaz702g(`6ii!Ap{7+kd0v+B1;G}fFR0}gpfqYN(f*RvJ8YJK*%ydMT8J3 zZZRbDAeUC^GN&g!+LlH}&GCqo?I<2uq_(K2F<4xB4%L*#mZg~f-#3{U5j|i%^_({F z%lp2!-goc2_uVhG=YncGf*Pj{8=}+c^x(_x?rs#i0FVs+A(~u~&sO}4f}cEFaNuKc ziY%f=*+dt_7x?|Ys0nz4^n%pE<_PpQgZ{t-)&NY_E#g#jMk8JZf&^d#Vc=#k2*dyb z2nXZ9ZD1Cd4<-ON2nIue6-*UPhM_}l!qaFl4NL_0fE4kvI&@_!o|1rEd^XB{;0Z7W z3%|VorAPRJe>H0{zBJR`=PjlkE7?glp zz%tMPUI%jAa+E8;<3O%ah%yV51KEBb$|XST*W1*&^5Ikcmf$Dzims*dATdIk>I%k5 zC10(0IsaHO+7P+vYORk%?;Fv&ivGP?$MXm<0|bIJ5CpDi2h?X^4~GoHHc4$uD};c) zR*+KmwSs*2TS4y3Zv|QJw}O2Bh7~Yx4sd{#U=bJq#shR0`TFR*8?jCW#!2hQwfb5| zzVAc5w3@Wkop6kynyI{>2D>QXZPMx90jGhKu`eH>t^=F_XThI=Z2t)5$Kanp?CO`G z*9M6*{UTMl+@3LAq<i^G!~;)}^y>Z7uf zro{=@lx#yiUZju7UV0fp7mJI-M+;jFR1$lT_AIa{UQ1?2ko)0e!xl6@)YI4Ndbl2X zinEE>aS_}|q{L8eiu-OCz2~jD`w`-%28#AZultCE zvM*5_detFZ`?BPYyj}Z@56Bo>UK@)FZF*2 z$Ridn5?$ki<*}1Lnc^PTM4BQ)ep7`ldQwj(*>s@Kb2^@niQt;Cj!Hb804IA|-|Q*h zLis0f3M>V0gLlAbQChQPpnth4)X2H7G?m1O6Kfp8u7r3K>i5&0SJFuRC0c#ze^uLF zU;rwjblyw%2Pz(Spr$@sp-tW0+pkdTC%Ot@_ur!S{@#|N`aKmk8n9*0u=vQPbxU_z zeyYB7@T72*g^Se67d^WMU5{R-U%y^fVdd|ym$ew(qnDdKt)ZUJ6wm%ZPp9HJ639sz z1n)ZEuJ<%6o>PiA&}w1JY%1n650Xi&Ngq4F9%tW>QnI?b6#swWo+27I*hS^32!1b_ z!no`)Y8IO#2lH+P-T%@w)N?^G%e54^RsitZM%D>)iVaa>ddeXZ!y^X?`(;&>Up9DS zE`3O037_BP-8uNVNK5X-=%=wxTi90WB+nby5J?>P!_4mx;ajHSrYv%ZRWE0GYd@_e z_k63c*2R9^J>2^cwXSx6jxN3QHQ&MCbNaAqsKaX$@I|xsKWhHl<%koO!co_Gd}O>y zv`@Jz-kcj5Agqe%c@wn|4S7C?f{9;I=vMAfDSSsUedg&jaI8w@^jBZw<9aeu1kY3{ zkH#?t(#RJk(Ox|b*^xsTGCajW$-6lu5&2d5Wg8|pYZZMby~Gn#a$a-BHcB8;FtVb* z7q*l?vNZV?9M*;fAz^zz2x0Nn4QWd>(hwq@@6`%9?h)?G>DM>@_LdkdmwCCdeTe#EDehQW}gXL&o8zojJ>b0((6Y8$^4j;&7B zq-wn{yTwFGOB^r*JBT2KJwy?7^**$@zg?>SQjY78r|oZpX%+Pd5U+&xxWJ4S3l=w# z+VUg?w(LULLh1{xbRd8aJU}zuM-qgob%4lv&B6PJ(@ecfE+sxVWtL88Gb}nGlObGX z1visfdauQObd-5PX;t;gwdK=ssYGO5o(s{x*D&XTk zfjiGhB_khhqX)TNkd>_?=r-Oxf(Esv+vqvsss@@SqSuA+zEle2UFmdA+(N}aj;4$K&&P4GlMH&9DbM4Xx$udD^Qe}U`Lu%1)?wE%%PEFtaix<=M0BYI38>7r zD>$ct7IJ(Z8ka$|4Dsl8Grut(TbjdEMHBh&Tgk*b7htY~pU_hA{=6s*MT)8`lij&t zF~#VmQ5K02m+qtrK2t|Uym32)@bUX8oICO%Iz%bpz4a8u3ALo^<)?#-b5f{8Dq<4u zX<=QbMh_m_Vy1xKcYh6rRFdw?*%2ljvD}wGP6;h|BQ}OQ8CjPP*devqxZYK*Z zmaCU?XAxFXOVH8fq%GW40^watXd`cFrvi~*9>L{HFb=w`*c4z3VC`& z{!$}sAV0b`O7l&XKE(F5uozTPC{4tj<=8=*+|gK`QA43}?GT<(MS*(x5mvxCm6XR( z<%l4KKC`b1!=goB9k<=?MPuxYjYK)g{13J@$FfF zZ%@sY+oUV2+<6E(>RnvCyw?D!<>z0Sn2Wb||T4x#FzFllgkARDSFMw-y6nb}_L z^QNV2$@Qyn7!P#OT|RGI$dERirtyFp%ICwW6x-4Wl_YJa6nP56eEwCq4yOtyqOi{_ z<9SmF6^Z<+Fvuo9Uh1F?M@usW{%E17Vi^p#KNa%(!;Yxhn%$PY9_~oe>86Xi%gNFu zBDgRU2E6frWZ^wdiV=^k2!(ZL@b5pNhkVDsr1u1J{ATDJ+A0vcwpuj5rB&?MOmq2s zHf0CPKqHg>?-S1^wmgHmI~LQZ|Jk7C;y0W<;SK@mOg`M_|0AeX|A)bBA!n|oxF0Ey zAw&3j#QZM?EqOusugx0`So!eL*gg>=|NFW2s|dF;1vpk6&h2%$Kzz=f-GSJe%4h0v zlKm2zMl}4EW-$ zG8uu3(PIN-C~A2R`RRtuwBd&qX<$L`UA06vPgkm2!;VU%S=zNcTHf$l_7X!?zU!Zl zL?A}Gc>FfH*SB3{8a7%jTeT!GruhTJPGlAve92iyJ4NYl$3A*89B9w%O9JuaGps%i z%{qQImlFG2Ps#Vv-fw=Ce&-k9n=x%cTj)g+361gADfkocBwY&f0{Ju*e|Ww2ho+Yr Ix{12~4S0=TfB*mh delta 6203 zcmeHLc~q3w6`%VtGt403u!s{jM+yo`5R^!ofU?C9g9>8M69EB52}KLPh7y?qhguQ1_}|R4K@$OY%?$z2nC{nAV4H&&8s1`|5h|=fEb_!7zM~JqW}Xi z3Ahos1;_?w0^aCW8E6aZqP&wVH%W*I+!~a_(w2@D(FM zutX{+S^uIXr0gIOZwQ|{2BZJ28AfBR78o#tXw?oIIs!dkB3-;_7{1y|v)o98#ztvSCWNmMX|>z z&-%N_{|K~~7MGtrMiGrc(az|^?TS$&(9;G;eT6IObscS!ElNvpx|031w%i<%b0JMM z=H?hSVnF)5dundJLGrN0+fjcY^`3zw8dzDHL$D=W{_&{^7gpermF_3 ze|V#9Cf1gn8uIKTF*M|rz3)Et&pq$|<(VT@o3=mDCX%Z|#O;s%+Fq-OjA~u0)mQj8 z#|?fFV)g@4WQNFW9&7xmr}enFw|P7{Wz220YU#J0N~HJf(=hKf&s@2BAL{djal@G8 zL#VwDqTKZyMDOHzc|8~ zv9XiHL(S$6(}(mvapwtYgv(SeqL(}8^LLH6zWWU z{|{tyz5La}b@Kje#HGxie~r+Ku|A?_g;|_<)%1KEb^AK}NNeAtc>A1juXdA&RzjVj zmmNg0&VtKE60cslncIytx+7~C`4RgYsDeIKhq%E={xq4B!|5(1ojR-rG7$Hf=o9|v zZbHmEbc(pvM75k}CVyUMq#}y%c-l-uiAK9u#d=l^egTO@ezJ^H$7q~;lNJj$$#Hir z5Cxat6Urfr)AB|S@jeqp^W{{G=eftb-Ak%s(KX!NmErDsI}U2!f#vri$`n+@J0_CW zF^&|DUPM{Wthe@%BZ?G98W1ge)9Du8l}jjY%-2NPMUhe+*bzK~b`kHiQSePjKJKsQr2tReA05)w)UQTU ziDzRS{@$;d{knYe;xWtxS(Iu!7{~2d6vFN4r0vLfgc^xf@|Gf+&e|f{%pqr}So)Qj zM)BC=G)IPS5xLwCPh|P7Y~su^y7ik_4m=mKZ5HLx6e(*AmzI-7CtvOF^5ZqsA*_c? zY)GUi9A-YhSx4of#OBB6=g>-8&IQM4u6X=FDCd`uo`bf~Ox{yW5!}}WwGS?&5Sq<_ zXJ{_B&&3(@OUb|?n`yp?th7Mha6Y$`D&?4k?iWjs&EcqJ(hl=5ZOU9)z}7SPIr4O& z9&;mk`wE)Ho%2Y`ab+-6Uk8hno4@4yJgyR(*Gp2%`CtcXEjyrlXE#OY1mZ@ynvJL2HR1M6i31QXbpYLDK%704cuFTy`Fl4 zOe%-lmS8`~D&`N*fZ-C=65{yI&~1ycT)TwM!_`#vR-L9Wum@^>M9U>1V$R|)959h- z2@I5R#3K>3!(u;_Yb&HzMljwG3*ZNkGD)mXo4|+aAUdlag5R#A#n4xk53@$|zQa^3 z!Z!u*$mLXYEdgOj259nr2sYeWPr>57un?H;M)a$i4)_Q<^U>MFz1?)5+lPL(LJ|O1 z6myD$aGXru{tDH>ZKS$hi`H=9O1hV-!?(2B{u!Q1ZC&)jcaL*biPu=%+GCUrYuZUUH&r_v^x1SxLVFERFx-EttSo6 z0h?hK%O+Y5yUE+YrcGp`#d2~v4jm+KWivNz!F9zYwvrlG%H>V+C(Gjn zh}YJ4kPO!KA@ZuP%Yp2!OZdzu(HTNM?)RBo1Sz*-R3nC4QyCBK1QD>bcHp=6&_$YJ z{M&AUW`!nEQ-x{ez_*=U=E&%5QFCa=3_CK14B6|icM@4~T~mZ!@bAMo;0z3M^%UVw POL)J IMAGE_DATA_DIRECTORY[0] EXPORT 导出表 mov [ebp + exp_AddressOfNames], eax mov ecx, [ebp + exp_AddressOfNames] mov edx, [ebp + varLocalFS30_A] // edx = 基地址 add edx, [ecx] // edx = 基地址 + 导出表地址 - mov [ebp + var_20], edx - mov eax, [ebp + var_20] // var_20 = IMAGE_EXPORT_DIRECTORY 地址 + mov [ebp + var_34], edx + mov eax, [ebp + var_34] // var_34 = IMAGE_EXPORT_DIRECTORY 地址 mov ecx, [ebp + varLocalFS30_A] // ecx = 基地址 add ecx, [eax + 0x20] // 获取 IMAGE_EXPORT_DIRECTORY +0x20 AddressOfNames 导出的函数名称表的RVA 也就是 函数名称表 mov [ebp + exp_AddressOfNames], ecx - mov edx, [ebp + var_20] + mov edx, [ebp + var_34] mov eax, [ebp + varLocalFS30_A] add eax, [edx + 0x24] // 获取 IMAGE_EXPORT_DIRECTORY +0x24 AddressOfNameOrdinals 导出函数序号表的RVA 也就是 函数序号表 mov [ebp + AddressOfNameOrdinals], eax mov ecx, 4 - mov [ebp + var_4], cx // 设置计数var_4,需要四个函数,找到一个 - 1 ,为 0 时查找完毕 + mov [ebp + var_28], cx // 设置计数var_28,需要四个函数,找到一个 - 1 ,为 0 时查找完毕 find_next_ker_fun: - movzx edx, [ebp+var_4] + movzx edx, [ebp+var_28] test edx, edx jle cmp_need_function @@ -559,39 +550,39 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() push ecx call calc_name_hash // 计算函数名称hash值 add esp, 4 - mov [ebp+var_30], eax // 计算的hash保存后进行比较 - cmp dword ptr[ebp+var_30], 0xEC0E4E8E // 0xEC0E4E8E = LoadLibraryA + mov [ebp+var_38], eax // 计算的hash保存后进行比较 + cmp dword ptr[ebp+var_38], 0xEC0E4E8E // 0xEC0E4E8E = LoadLibraryA jz find_function_hash - cmp dword ptr[ebp+var_30], 0x7C0DFCAA // 0x7C0DFCAA = GetProcAddress + cmp dword ptr[ebp+var_38], 0x7C0DFCAA // 0x7C0DFCAA = GetProcAddress jz find_function_hash - cmp dword ptr[ebp+var_30], 0x91AFCA54 // 0x91AFCA54 = VirtualAlloc + cmp dword ptr[ebp+var_38], 0x91AFCA54 // 0x91AFCA54 = VirtualAlloc jz find_function_hash - cmp dword ptr[ebp+var_30], 0x7946C61B // 0x7946C61B = VirtualProtect + cmp dword ptr[ebp+var_38], 0x7946C61B // 0x7946C61B = VirtualProtect jnz no_find_function_hash find_function_hash: - mov edx, [ebp+var_20] // var_20 = IMAGE_EXPORT_DIRECTORY 地址 + mov edx, [ebp+var_34] // var_34 = IMAGE_EXPORT_DIRECTORY 地址 mov eax, [ebp+varLocalFS30_A] add eax, [edx+0x1C] // IMAGE_EXPORT_DIRECTORY + 0x1C = AddressOfFunctions 导出的函数地址的 地址表 RVA 也就是 函数地址表 - mov [ebp+var_28], eax + mov [ebp+var_3c], eax mov ecx, [ebp+AddressOfNameOrdinals]// 保存序号索引 movzx edx, word ptr [ecx] - mov eax, [ebp+var_28] + mov eax, [ebp+var_3c] lea ecx, [eax+edx*4] // 序号索引IMAGE_EXPORT_DIRECTORY 找到函数地址 - mov [ebp+var_28], ecx // var_28 = AddressOfFunctions[AddressOfNameOrdinals] + mov [ebp+var_3c], ecx // var_3c = AddressOfFunctions[AddressOfNameOrdinals] - cmp dword ptr[ebp+var_30], 0xEC0E4E8E + cmp dword ptr[ebp+var_38], 0xEC0E4E8E jnz no_LoadLibraryA - mov edx, [ebp+var_28] + mov edx, [ebp+var_3c] mov eax, [ebp+varLocalFS30_A] // eax = varLocalFS30_A = 基地址 add eax, [edx] // 计算得到函数地址 mov [ebp+LoadLibraryA], eax // 保存到局部堆栈LoadLibraryA jmp find_index_dec // 查找下一个 no_LoadLibraryA: - cmp dword ptr[ebp+var_30], 0x7C0DFCAA + cmp dword ptr[ebp+var_38], 0x7C0DFCAA jnz no_GetProcAddress - mov ecx, [ebp+var_28] + mov ecx, [ebp+var_3c] mov edx, [ebp+varLocalFS30_A] // edx = varLocalFS30_A = 基地址 add edx, [ecx] // 计算得到函数地址 mov [ebp+ pGetProcAddress], edx // 保存到局部堆栈GetProcAddress @@ -599,26 +590,26 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() no_GetProcAddress: - cmp dword ptr[ebp+var_30], 0x91AFCA54 + cmp dword ptr[ebp+var_38], 0x91AFCA54 jnz no_VirtualAlloc - mov eax, [ebp+var_28] + mov eax, [ebp+var_3c] mov ecx, [ebp+varLocalFS30_A] // ecx = varLocalFS30_A = 基地址 add ecx, [eax] // 计算得到函数地址 mov [ebp+VirtualAlloc], ecx // 保存到局部堆栈VirtualAlloc jmp find_index_dec // 查找下一个 no_VirtualAlloc: - cmp dword ptr[ebp+var_30], 0x7946C61B + cmp dword ptr[ebp+var_38], 0x7946C61B jnz find_index_dec - mov edx, [ebp+var_28] + mov edx, [ebp+var_3c] mov eax, [ebp+varLocalFS30_A] // eax = varLocalFS30_A = 基地址 add eax, [edx] // 计算得到函数地址VirtualProtect mov [ebp+ pVirtualProtect], eax // 保存到局部堆栈 find_index_dec: - mov cx, [ebp+var_4] // 找到函数后 计数 - 1 + mov cx, [ebp+var_28] // 找到函数后 计数 - 1 sub cx, 1 - mov [ebp+var_4], cx + mov [ebp+var_28], cx no_find_function_hash: mov edx, [ebp+exp_AddressOfNames] @@ -641,29 +632,29 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() mov eax, [ebp+varLocalFS30_A] mov ecx, [ebp+varLocalFS30_A] add ecx, [eax+0x3C] // 获取PE IMAGE_DOS_HRADER e_lfanew - mov [ebp+var_20], ecx + mov [ebp+var_34], ecx mov edx, 8 imul eax, edx, 0 - mov ecx, [ebp+var_20] + mov ecx, [ebp+var_34] lea edx, [ecx+eax+0x78] // 获取IMAGE_OPTIONAL_HEADER -> IMAGE_DATA_DIRECTORY[0] EXPORT 导出表 mov [ebp+exp_AddressOfNames], edx mov eax, [ebp+exp_AddressOfNames] mov ecx, [ebp+varLocalFS30_A] // ecx = 基地址 add ecx, [eax] // 基地址 + 导出表地址 - mov [ebp+var_20], ecx - mov edx, [ebp+var_20] + mov [ebp+var_34], ecx + mov edx, [ebp+var_34] mov eax, [ebp+varLocalFS30_A] add eax, [edx+0x20] // 获取 IMAGE_EXPORT_DIRECTORY +0x20 AddressOfNames mov [ebp+exp_AddressOfNames], eax - mov ecx, [ebp+var_20] + mov ecx, [ebp+var_34] mov edx, [ebp+varLocalFS30_A] add edx, [ecx+0x24] // 获取 IMAGE_EXPORT_DIRECTORY +0x24 AddressOfNameOrdinals mov [ebp+AddressOfNameOrdinals], edx mov eax, 1 - mov [ebp+var_4], ax + mov [ebp+var_28], ax find_next_nt_fun: // 同上面一样 - movzx ecx, [ebp+var_4] // 需要一个函数 var_4 = 1 + movzx ecx, [ebp+var_28] // 需要一个函数 var_28 = 1 test ecx, ecx jle check_function mov edx, [ebp+exp_AddressOfNames] // exp_AddressOfNames = 函数名称表[] @@ -672,29 +663,29 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() push eax call calc_name_hash add esp, 4 - mov [ebp+var_30], eax - cmp dword ptr[ebp+var_30], 0x534C0AB8 // 0x534C0AB8 = NtFlushInstructionCache + mov [ebp+var_38], eax + cmp dword ptr[ebp+var_38], 0x534C0AB8 // 0x534C0AB8 = NtFlushInstructionCache jnz no_NtFlushInstructionCache - mov ecx, [ebp+var_20] + mov ecx, [ebp+var_34] mov edx, [ebp+varLocalFS30_A] add edx, [ecx+0x1C] - mov [ebp+var_28], edx + mov [ebp+var_3c], edx mov eax, [ebp+AddressOfNameOrdinals] movzx ecx, word ptr [eax] - mov edx, [ebp+var_28] + mov edx, [ebp+var_3c] lea eax, [edx+ecx*4] - mov [ebp+var_28], eax - cmp dword ptr[ebp+var_30], 0x534C0AB8 + mov [ebp+var_3c], eax + cmp dword ptr[ebp+var_38], 0x534C0AB8 jnz find_nt_index_dec - mov ecx, [ebp+var_28] + mov ecx, [ebp+var_3c] mov edx, [ebp+varLocalFS30_A] add edx, [ecx] mov [ebp+pNtFlushInstructionCache], edx // 获取函数地址NtFlushInstructionCache保存 find_nt_index_dec: - mov ax, [ebp+var_4] + mov ax, [ebp+var_28] sub ax, 1 - mov [ebp+var_4], ax + mov [ebp+var_28], ax no_NtFlushInstructionCache: mov ecx, [ebp+exp_AddressOfNames] @@ -717,78 +708,78 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() jmp find_moudle_over continue_find_function: - mov eax, [ebp+var_C] + mov eax, [ebp+varLocalFS30_B] mov ecx, [eax] - mov [ebp+var_C], ecx + mov [ebp+varLocalFS30_B], ecx jmp continue_find find_moudle_over: mov edx, [ebp+PEAddress] mov eax, [ebp+PEAddress] add eax, [edx+3Ch] - mov [ebp+var_24], eax + mov [ebp+var_28c], eax push 0x04 // PAGE_READWRITE 区域不可执行代码,应用程序可以读写该区域 push 0x3000 // MEM_COMMIT | MEM_RESERV - mov ecx, [ebp+var_24] + mov ecx, [ebp+var_28c] mov edx, [ecx+0x50] // PE signature 0x18 + 0x38 SizeOfImage 映像装入内存后的总大小 add edx, 0x3C00000 // dwSize push edx push 0x0 call [ebp+ pVirtualAlloc] // 申请一块 3C0000+SizeOfImage大小的内存 - mov [ebp+var_8], eax // var_8 = mem_address - mov eax, [ebp+var_24] // var_24 = signature + mov [ebp+varLocalFS30_A], eax // varLocalFS30_A = mem_address + mov eax, [ebp+var_28c] // var_28c = signature mov ecx, [eax+0x54] // ecx = SizeOfHeaders 0x18 + 0x3c - mov [ebp+var_C], ecx + mov [ebp+varLocalFS30_B], ecx mov edx, [ebp+PEAddress] // PEAddress = 4D5A address mov [ebp+BaseDllName], edx // BaseDllName = PEAddress - mov eax, [ebp+var_8] + mov eax, [ebp+varLocalFS30_A] mov [ebp+name_hash], eax // name_hash = mem_address - mov ecx, [ebp+var_24] + mov ecx, [ebp+var_28c] movzx edx, word ptr [ecx+0x14] // edx = WORD SizeOfOptionalHeader - mov eax, [ebp+var_24] + mov eax, [ebp+var_28c] lea ecx, [eax+edx+0x18] // signature + SizeOfOptionalHeader + sizeof signature = struct _IMAGE_SECTION_HEADER address 区段地址 - mov [ebp+var_C], ecx // var_C = 区段地址 - mov edx, [ebp+var_24] + mov [ebp+varLocalFS30_B], ecx // varLocalFS30_B = 区段地址 + mov edx, [ebp+var_28c] movzx eax, word ptr [edx+0x06] // signature + 0x04 + 0x02 - mov [ebp+var_3C], eax // var_3C = NumberOfSections 节的数量 + mov [ebp+var_50], eax // var_50 = NumberOfSections 节的数量 loc_463585: - mov ecx, [ebp+var_3C] - mov [ebp+var_58], ecx // var_58 = 剩余要处理的Sections数量 index - mov edx, [ebp+var_3C] + mov ecx, [ebp+var_50] + mov [ebp+var_54], ecx // var_54 = 剩余要处理的Sections数量 index + mov edx, [ebp+var_50] sub edx, 1 - mov [ebp+var_3C], edx - cmp dword ptr[ebp+var_58], 0 // 区段是否都处理了 + mov [ebp+var_50], edx + cmp dword ptr[ebp+var_54], 0 // 区段是否都处理了 jz loc_463614 - mov eax, [ebp+var_C] // var_C = 区段地址 - mov ecx, [ebp+var_8] // var_8 = mem_address + mov eax, [ebp+varLocalFS30_B] // varLocalFS30_B = 区段地址 + mov ecx, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address add ecx, [eax+0x0C] // 申请的地址计算 基址 + 区段地址 +0x0c = struct _IMAGE_SECTION_HEADER->VirtualAddress 节区的 RVA 地址 mov [ebp+BaseDllName], ecx // BaseDllName = SECTION VirtualAddress new mem 新地址 - mov edx, [ebp+var_C] + mov edx, [ebp+varLocalFS30_B] mov eax, [ebp+PEAddress] // eax = 4D5A address add eax, [edx+0x14] // 取值 4D5A address + PointerToRawData = 区段地址 + 0x14 = struct _IMAGE_SECTION_HEADER->PointerToRawData 文件中区段偏移 mov [ebp+name_hash], eax // name_hash = _IMAGE_SECTION_HEADER->PointerToRawData 在文件中的偏移量 - mov ecx, [ebp+var_C] // var_C = 区段地址 + mov ecx, [ebp+varLocalFS30_B] // varLocalFS30_B = 区段地址 mov edx, [ecx+0x10] // - mov [ebp+var_14], edx // var_14 = _IMAGE_SECTION_HEADER->SizeOfRawData 在文件中对齐后的尺寸 - cmp dword ptr[ebp+var_50], 0 + mov [ebp+var_58], edx // var_58 = _IMAGE_SECTION_HEADER->SizeOfRawData 在文件中对齐后的尺寸 + cmp dword ptr[ebp+var_5c], 0 jnz loc_4635C7 mov eax, [ebp+BaseDllName] - mov [ebp+var_50], eax // var_50 = SECTION VirtualAddress new mem 新地址 + mov [ebp+var_5c], eax // var_5c = SECTION VirtualAddress new mem 新地址 loc_4635C7: - cmp dword ptr[ebp+var_4C], 0 + cmp dword ptr[ebp+var_60], 0 jnz loc_4635D3 - mov ecx, [ebp+var_14] - mov [ebp+var_4C], ecx // var_4C = SizeOfRawData + mov ecx, [ebp+var_58] + mov [ebp+var_60], ecx // var_60 = SizeOfRawData loc_4635D3: - mov edx, [ebp+var_14] - mov [ebp+var_5C], edx // var_5C = SizeOfRawData - mov eax, [ebp+var_14] + mov edx, [ebp+var_58] + mov [ebp+var_64], edx // var_64 = SizeOfRawData + mov eax, [ebp+var_58] sub eax, 1 // 拷贝计数size - 1 - mov [ebp+var_14], eax // var_14 = SizeOfRawData 在文件中对齐后的尺寸 - 1 - cmp dword ptr[ebp+var_5C], 0 // 为 0 拷贝完成 + mov [ebp+var_58], eax // var_58 = SizeOfRawData 在文件中对齐后的尺寸 - 1 + cmp dword ptr[ebp+var_64], 0 // 为 0 拷贝完成 jz loc_463606 mov ecx, [ebp+BaseDllName] // BaseDllName = SECTION VirtualAddress new mem 新地址 mov edx, [ebp+name_hash] // PointerToRawData @@ -803,19 +794,19 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() jmp loc_4635D3 // 跳转后文件对其尺寸 - 1 为 0 时区段拷贝完毕 loc_463606: - mov eax, [ebp+var_C] // var_C = 区段地址 + mov eax, [ebp+varLocalFS30_B] // varLocalFS30_B = 区段地址 add eax, 0x28 - mov [ebp+var_C], eax // 下一个区段 + mov [ebp+varLocalFS30_B], eax // 下一个区段 jmp loc_463585 loc_463614: mov ecx, 8 shl ecx, 0 // [1] 数据目录表第二项 导入表 IMAGE_DIRECTORY_ENTRY_IMPORT - mov edx, [ebp+var_24] // var_24 = signature + mov edx, [ebp+var_28c] // var_28c = signature lea eax, [edx+ecx+0x78] // 0x78 + 0x08 mov [ebp+BaseDllName], eax mov ecx, [ebp+BaseDllName] - mov edx, [ebp+var_8] // var_8 = mem_address + mov edx, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address add edx, [ecx] // mem_address + VirtualAddress mov [ebp+name_hash], edx // name_hash = 申请地址的导入表 loc_463631: @@ -823,66 +814,66 @@ extern "C" __declspec(dllexport) void ReflectiveLoader() cmp dword ptr [eax+0x0C], 0 // 判断 模块名称 0x0c _IMAGE_EXPORT_DIRECTORY Name jz loc_463729 mov ecx, [ebp+name_hash] // name_hash = 申请地址的导入表 - mov edx, [ebp+var_8] // var_8 = mem_address + mov edx, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address add edx, [ecx+0x0C] // 名称读取 dllName push edx call [ebp+ pLoadLibraryA] // 获取模块句柄 mov [ebp+module_handle], eax // module_handle = 模块句柄 mov eax, [ebp+name_hash] // name_hash = 申请地址的导入表 - mov ecx, [ebp+var_8] // var_8 = mem_address + mov ecx, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address add ecx, [eax] // 找到新内存的导入表位置 - mov [ebp+var_14], ecx // var_14 = new_mem_import + mov [ebp+var_58], ecx // var_58 = new_mem_import mov edx, [ebp+name_hash] - mov eax, [ebp+var_8] + mov eax, [ebp+varLocalFS30_A] add eax, [edx+0x10] // IMAGE_IMPORT_DESCRIPTOR -> FirstThunk - mov [ebp+var_C], eax // var_C = MAGE_IMPORT_DESCRIPTOR -> FirstThunk + mov [ebp+varLocalFS30_B], eax // varLocalFS30_B = MAGE_IMPORT_DESCRIPTOR -> FirstThunk loc_463665: - mov ecx, [ebp+var_C] + mov ecx, [ebp+varLocalFS30_B] cmp dword ptr [ecx], 0 // 判断FirstThunk是否为0 jz loc_46371B // 为0跳转 - cmp dword ptr[ebp+var_14], 0 // 判断新内存的导入表是否为 + cmp dword ptr[ebp+var_58], 0 // 判断新内存的导入表是否为 jz loc_4636E0 - mov edx, [ebp+var_14] + mov edx, [ebp+var_58] mov eax, [edx] and eax, 0x80000000 // 当IMAGE_THUNK_DATA 结构体最高位为1时,表示函数以序号导入,此时低31位被看成函数序号使用。 jz loc_4636E0 mov ecx, [ebp+module_handle] // 序号获取导出函数 mov edx, [ebp+module_handle] add edx, [ecx+0x3C] - mov [ebp+var_20], edx + mov [ebp+var_34], edx mov eax, 8 imul ecx, eax, 0 - mov edx, [ebp+var_20] + mov edx, [ebp+var_34] lea eax, [edx+ecx+0x78] mov [ebp+exp_AddressOfNames], eax mov ecx, [ebp+exp_AddressOfNames] mov edx, [ebp+module_handle] add edx, [ecx] - mov [ebp+var_20], edx - mov eax, [ebp+var_20] + mov [ebp+var_34], edx + mov eax, [ebp+var_34] mov ecx, [ebp+module_handle] add ecx, [eax+0x1C] - mov [ebp+var_28], ecx - mov edx, [ebp+var_14] + mov [ebp+var_3c], ecx + mov edx, [ebp+var_58] mov eax, [edx] and eax, 0x0FFFF - mov ecx, [ebp+var_20] + mov ecx, [ebp+var_34] sub eax, [ecx+0x10] - mov edx, [ebp+var_28] + mov edx, [ebp+var_3c] lea eax, [edx+eax*4] - mov [ebp+var_28], eax - mov ecx, [ebp+var_28] + mov [ebp+var_3c], eax + mov ecx, [ebp+var_3c] mov edx, [ebp+module_handle] add edx, [ecx] - mov eax, [ebp+var_C] + mov eax, [ebp+varLocalFS30_B] mov [eax], edx jmp loc_4636FE loc_4636E0: // 名称导入 - mov ecx, [ebp+var_C] - mov edx, [ebp+var_8] + mov ecx, [ebp+varLocalFS30_B] + mov edx, [ebp+varLocalFS30_A] add edx, [ecx] mov [ebp+BaseDllName], edx mov eax, [ebp+BaseDllName] @@ -891,18 +882,18 @@ loc_4636E0: // 名称导入 mov ecx, [ebp+module_handle] push ecx call [ebp+pGetProcAddress] // 读取函数名称获取函数地址 - mov edx, [ebp+var_C] + mov edx, [ebp+varLocalFS30_B] mov [edx], eax // 填充导入表IAT loc_4636FE: - mov eax, [ebp+var_C] // 下一个函数 + mov eax, [ebp+varLocalFS30_B] // 下一个函数 add eax, 4 - mov [ebp+var_C], eax - cmp dword ptr[ebp+var_14], 0 + mov [ebp+varLocalFS30_B], eax + cmp dword ptr[ebp+var_58], 0 jz loc_463716 - mov ecx, [ebp+var_14] + mov ecx, [ebp+var_58] add ecx, 4 - mov [ebp+var_14], ecx + mov [ebp+var_58], ecx loc_463716: jmp loc_463665 // 循环填充 @@ -914,20 +905,20 @@ loc_46371B: jmp loc_463631 // 下一个导入表结构 loc_463729: - mov eax, [ebp+var_24] // var_24 = signature - mov ecx, [ebp+var_8] // var_8 = mem_address + mov eax, [ebp+var_28c] // var_28c = signature + mov ecx, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address sub ecx, [eax+0x34] // 当前加载基址 - 默认加载基址 meMaddress - ImageBase mov [ebp+address], ecx mov edx, 8 imul eax, edx, 5 // 第6个表 重定位表 - mov ecx, [ebp+var_24] + mov ecx, [ebp+var_28c] lea edx, [ecx+eax+0x78] mov [ebp+BaseDllName], edx mov eax, [ebp+BaseDllName] cmp dword ptr [eax+4], 0 jz loc_4638F2 // 修复结束跳转 mov ecx, [ebp+BaseDllName] - mov edx, [ebp+var_8] + mov edx, [ebp+varLocalFS30_A] add edx, [ecx] // 定位IMAGE_BASE_RELOCATION mov [ebp+name_hash], edx // name_hash = _IMAGE_BASE_RELOCATION @@ -936,9 +927,9 @@ loc_46375F: cmp dword ptr [eax+4], 0 // IMAGE_BASE_RELOCATION -> SizeOfBlock // 结构体大小,包含TypeOffset jz loc_4638F2 mov ecx, [ebp+name_hash] - mov edx, [ebp+var_8] // var_8 = mem_address + mov edx, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address add edx, [ecx] // mem_address + 需要重定位的区域的位置RVA - mov [ebp+var_C], edx // var_C = 需要重定位的区域 + mov [ebp+varLocalFS30_B], edx // varLocalFS30_B = 需要重定位的区域 mov eax, [ebp+name_hash] mov ecx, [eax+4] // ecx = SizeOfBlock sub ecx, 8 @@ -946,17 +937,17 @@ loc_46375F: mov [ebp+BaseDllName], ecx // BaseDllName = reloc_number mov edx, [ebp+name_hash] add edx, 8 - mov [ebp+var_14], edx // var_14 = TypeOffset[1]; // 存放相对于VirtualAddress的偏移 + mov [ebp+var_58], edx // var_58 = TypeOffset[1]; // 存放相对于VirtualAddress的偏移 loc_46378E: mov eax, [ebp+BaseDllName] - mov [ebp+var_60], eax + mov [ebp+var_70], eax mov ecx, [ebp+BaseDllName] sub ecx, 1 mov [ebp+BaseDllName], ecx // 总数 - 1 - cmp dword ptr[ebp+var_60], 0 + cmp dword ptr[ebp+var_70], 0 jz loc_4638E1 - mov edx, [ebp+var_14] + mov edx, [ebp+var_58] mov ax, [edx] // 获取重定位项 TypeOffset是一个以2字节为一个元素的数组 其中元素的低12位才是偏移地址,高4位是属性 shr ax, 0x0C and ax, 0x0F @@ -964,22 +955,22 @@ loc_46378E: cmp ecx, 0x0A jnz loc_4637ED mov edx, 0x0FFF - mov eax, [ebp+var_14] + mov eax, [ebp+var_58] and dx, [eax] movzx ecx, dx - mov edx, [ebp+var_C] + mov edx, [ebp+varLocalFS30_B] mov eax, [edx+ecx] add eax, [ebp+address] mov ecx, 0x0FFF - mov edx, [ebp+var_14] + mov edx, [ebp+var_58] and cx, [edx] movzx ecx, cx - mov edx, [ebp+var_C] + mov edx, [ebp+varLocalFS30_B] mov [edx+ecx], eax jmp loc_4638D3 loc_4637ED: - mov eax, [ebp+var_14] + mov eax, [ebp+var_58] mov cx, [eax] shr cx, 0x0C and cx, 0x0F @@ -987,22 +978,22 @@ loc_4637ED: cmp edx, 3 // 当此标记为0011(3)时低12为才有效 TypeOffset jnz loc_463833 mov eax, 0x0FFF - mov ecx, [ebp+var_14] + mov ecx, [ebp+var_58] and ax, [ecx] movzx edx, ax - mov eax, [ebp+var_C] // self_baseaddress 加载基址 + mov eax, [ebp+varLocalFS30_B] // self_baseaddress 加载基址 mov ecx, [eax+edx] // 默认加载基址 + 重定位列表项 add ecx, [ebp+address] // 计算当前基址 重定位后的地址 mov edx, 0x0FFF - mov eax, [ebp+var_14] + mov eax, [ebp+var_58] and dx, [eax] movzx edx, dx - mov eax, [ebp+var_C] + mov eax, [ebp+varLocalFS30_B] mov [eax+edx], ecx // 修复重定位 jmp loc_4638D3 loc_463833: - mov ecx, [ebp+var_14] + mov ecx, [ebp+var_58] mov dx, [ecx] shr dx, 0x0C and dx, 0x0F @@ -1010,26 +1001,26 @@ loc_463833: cmp eax, 1 jnz loc_463886 mov ecx, 0x0FFF - mov edx, [ebp+var_14] + mov edx, [ebp+var_58] and cx, [edx] movzx eax, cx mov ecx, [ebp+address] shr ecx, 0x10 and ecx, 0x0FFFF movzx edx, cx - mov ecx, [ebp+var_C] + mov ecx, [ebp+varLocalFS30_B] movzx eax, word ptr [ecx+eax] add eax, edx mov ecx, 0x0FFF - mov edx, [ebp+var_14] + mov edx, [ebp+var_58] and cx, [edx] movzx ecx, cx - mov edx, [ebp+var_C] // 修复重定位 + mov edx, [ebp+varLocalFS30_B] // 修复重定位 mov [edx+ecx], ax jmp loc_4638D3 loc_463886: - mov eax, [ebp+var_14] + mov eax, [ebp+var_58] mov cx, [eax] shr cx, 0x0C and cx, 0x0F @@ -1037,26 +1028,26 @@ loc_463886: cmp edx, 2 jnz loc_4638D3 mov eax, 0x0FFF - mov ecx, [ebp+var_14] + mov ecx, [ebp+var_58] and ax, [ecx] movzx edx, ax mov eax, [ebp+address] and eax, 0x0FFFF movzx ecx, ax - mov eax, [ebp+var_C] + mov eax, [ebp+varLocalFS30_B] movzx edx, word ptr [eax+edx] add edx, ecx mov eax, 0x0FFF - mov ecx, [ebp+var_14] + mov ecx, [ebp+var_58] and ax, [ecx] movzx eax, ax - mov ecx, [ebp+var_C] // 修复重定位 + mov ecx, [ebp+varLocalFS30_B] // 修复重定位 mov [ecx+eax], dx loc_4638D3: - mov edx, [ebp+var_14] + mov edx, [ebp+var_58] add edx, 2 - mov [ebp+var_14], edx + mov [ebp+var_58], edx jmp loc_46378E loc_4638E1: @@ -1068,33 +1059,33 @@ loc_4638E1: loc_4638F2: - mov edx, [ebp+var_24] // var_24 = signature - mov eax, [ebp+var_8] // var_8 = mem_address + mov edx, [ebp+var_28c] // var_28c = signature + mov eax, [ebp+varLocalFS30_A] // varLocalFS30_A = mem_address add eax, [edx+0x28] // 入口点 - mov [ebp+var_C], eax + mov [ebp+varLocalFS30_B], eax push 0 push 0 push 0xFFFFFFFF call [ebp+ pNtFlushInstructionCache] - lea ecx, [ebp+var_64] + lea ecx, [ebp+var_288] push ecx push 0x20 - mov edx, [ebp+var_4C] + mov edx, [ebp+var_60] push edx - mov eax, [ebp+var_50] + mov eax, [ebp+var_5c] push eax call [ebp+ pVirtualProtect] push 0 push 1 - mov ecx, [ebp+var_8] + mov ecx, [ebp+varLocalFS30_A] push ecx - call [ebp+var_C] // call 入口点 + call [ebp+varLocalFS30_B] // call 入口点 push 0 push 4 - mov edx, [ebp+var_8] + mov edx, [ebp+varLocalFS30_A] push edx - call [ebp+var_C] - mov eax, [ebp+var_C] + call [ebp+varLocalFS30_B] + mov eax, [ebp+varLocalFS30_B] mov esp, ebp pop ebp retn diff --git a/bin/server/CcMainDll.dll b/bin/server/CcMainDll.dll index eeafd0dd7d93ca443486c4bf8310e1fbeed99d64..04084c7dd88d56300d7550e92c37eb42b48dee7d 100644 GIT binary patch delta 12291 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