看雪CTF2017秋季赛第五题分析

漏洞分析丨HEVD-0x1.StackOverflow[win7x86] 视频制作不易,求三联支持,拜谢~添加公众账号“极安御信安全研究院”,报暗号:“资料” 即可领取视频相关工具、源码、学习资料,和其他逆向工程免费课。进交流群报暗号“交流群” 网络安全交流群QQ:434238324... 阅读详情
void __stdcall keygen(SomeArr *computed, const char *input)
{
  signed int v2; // ebx
  int v3; // edi
  char v4; // al
  char *base18ed; // [esp+0h] [ebp-4h]
  signed int base18_len; // [esp+10h] [ebp+Ch]

  base18ed = (char *)malloc(3 * strlen(input));
  compute_base18(input, base18ed);              // 这里先看输入输出的值,然后在函数里参看关键点的值,进行函数分析
                                                // 把字符串按62进制转换成整形数据,把整形数据转换成18进制表示的字符
  base18_len = strlen(base18ed);                // base18ed
                                                // 012E77A8  45 44 41 48 45 34 35 30  EDAHE450
                                                // 012E77B0  43 37 34 31 47 48 34 34  C741GH44
                                                // 012E77B8  31 45 31 31 42 48 38 34  1E11BH84
  v2 = 0;
  if ( base18_len > 0 )
  {
    v3 = base18_len;
    do
    {
      v4 = base18ed[v2];
      if ( v4 < '0' || v4 > '9' )               // 18进制字符串转换成整形
      {
        if ( v4 >= 'A' && v4 <= 'H' )
          v3 = v4 - '7';
      }
      else
      {
        v3 = v4 - '0';
      }
      mult_arrays_pow(v3 / 3, v3 % 3 + 1, (int)computed);
      ++v2;
    }
    while ( v2 < base18_len );
  }
  free(base18ed);
}

这里computed_base18对内部字符串和输入字符串进行变换,经过mult_arrays_pows对computed进行操作。最后让computed和初始化的一个块进行对比。

char *__stdcall compute_base18(const char *input, char *out)
{
  int v2; // eax
  char v3; // al
  int v4; // ebx
  _DWORD *v5; // eax
  int v6; // ebx
  char v7; // al
  char *result; // eax
  signed int v9; // [esp+10h] [ebp-208h]
  int i; // [esp+14h] [ebp-204h]
  BigInt v11; // [esp+18h] [ebp-200h]
  BigInt res2; // [esp+60h] [ebp-1B8h]
  char v13; // [esp+A0h] [ebp-178h]
  int v14; // [esp+A4h] [ebp-174h]
  unsigned int res1; // [esp+A8h] [ebp-170h]
  int v16; // [esp+ECh] [ebp-12Ch]
  BigInt num_18; // [esp+F0h] [ebp-128h]
  BigInt num_62; // [esp+138h] [ebp-E0h]
  BigInt inputa; // [esp+180h] [ebp-98h]
  char v20; // [esp+1C8h] [ebp-50h]

  v14 = -1;
  v13 = 0;
  memset(&res2, 0, 0x40u);
  initStruct(1, 0, (int)&res1);
  initStruct(62, 0, (int)&num_62);
  initStruct(18, 0, (int)&num_18);
  v9 = strlen(input);
  v2 = 0;
  for ( i = 0; v2 < v9; i = v2 )
  {
    v3 = input[v2];
    if ( v3 < '0' || v3 > '9' )                 // 字符串转换成单个62为单位的十进制值
    {
      if ( v3 < 'A' || v3 > 'Z' )
      {
        if ( v3 < 'a' || v3 > 'z' )
          v4 = -1;
        else
          v4 = v3 - 0x3D;
      }
      else
      {
        v4 = v3 - 0x37;
      }
    }
    else
    {
      v4 = v3 - 0x30;
    }
    if ( v4 != -1 )                             // 第二次变换   按权重乘以相应个数的62
    {
      initStruct(v4, 0, (int)&inputa);          // 第一次执行inputa=v4
      v5 = BigIntMultiply((int)&res1, &v20, (int)&inputa);// res
                                                // 100161AD0  00 00 3E C4 23 89 B3 3B  ..>?壋;
                                                // 00161AD8  44 8F 58 4E 25 00 00 00  D廥N%...
      HP_Plus((int)&res2, &v11, (int)v5);       // res2
                                                // 00161A88  88 41 DD 2E 43 36 6E 25  圓?C6n%
                                                // 00161A90  5E 45 C0 38 04 00 00 00  ^E?...
                                                // 这个res2应该是字符串转换成以62进制的数值
                                                // 438c0455e256e36432edd4188
      HP_Mutiply((char *)&res1, (int)&num_62, (int *)&v11);
    }
    v2 = i + 1;
  }                                             // 经过上个循环变换,接下来的循环会利用res1来进行计算。这里猜测res1为上个循环输出的值
  v6 = 0;
  if ( v14 >= 0 )
  {
    while ( 1 )                                 // 第三次变换    62进制转换为18进制
    {
      qmemcpy(&res1, BigIntMod((int *)&res2, (int *)&v11, (int)&num_18), 0x48u);
      qmemcpy(&res2, BigIntDiv((int *)&res2, (int *)&v11, (int)&num_18), 0x48u);
      if ( res1 <= 9 && !v16 )                  // 第四次变换  18进制转换
        break;

      if ( res1 - 10 <= 7 && !v16 )
      {
        v7 = res1 + '7';
        goto LABEL_22;
      }
      if ( v16 != -1 || res1 )
      {
        printf("error %d %d \n", res1, v16);
        goto LABEL_28;
      }
      out[v6] = '0';
LABEL_26:
      ++v6;
LABEL_28:
      if ( v14 < 0 )
        goto LABEL_29;
    }
    v7 = res1 + '0';
LABEL_22:
    out[v6] = v7;
    goto LABEL_26;
  }
LABEL_29:
  result = out;
  out[v6] = 0;
  return result;
}

这里分析了半天,原因是一下这几句。参数很多,根本搞不清输入输出到底是那个

initStruct(v4, 0, (int)&inputa);          // 第一次执行inputa=v4
v5 = BigIntMultiply((int)&res1, &v20, (int)&inputa);
HP_Plus((int)&res2, &v11, (int)v5);       // res2
HP_Mutiply((char *)&res1, (int)&num_62, (int *)&v11);

最后发现接下来利用的几个参数中有res2和res1,

qmemcpy(&res1, BigIntMod((int *)&res2, (int *)&v11, (int)&num_18), 0x48u);
qmemcpy(&res2, BigIntDiv((int *)&res2, (int *)&v11, (int)&num_18), 0x48u);

通过分析这几个关键的参数的分析,可以大致得到整个函数的算法详情。
如果跟进BigIntMultiply、HP_Plus、HP_Mutiply三个函数,发现分析起来很麻烦。这里逆向的话,还是要根据关键参数的分析来分析算法的具体流程,如果完全跟进的话会比较麻烦。

sa="KanXueCrackMe2017"
sb="EDAHE450C741GH441E11BH84"
mid=334476251944397096847543189896
aplb="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
apls="abcdefghijklmnopqrstuvwxyz"
#[7, 1, 0, 2, 40, 22, 46, 38, 36, 53, 12, 40, 56, 33, 49, 36, 20]
sa=sa[::-1]
print sa
sb=sb[::-1]
print sb
print mid
def str_to_sixtytwo():
    l=[]
    for i in range(len(sa)):
        if(ord(sa[i])>=ord('0') and ord(sa[i])<=ord('9')):
            l.append(ord(sa[i])-ord('0'))
        if(ord(sa[i])>=ord('a') and ord(sa[i])<=ord('z')):
            l.append(ord(sa[i])-ord('='))
        if(ord(sa[i])>=ord('A') and ord(sa[i])<=ord('Z')):
            l.append(ord(sa[i])-ord('7'))
    print l

    n=0

    for i in range(len(l)):
        n=n*62
        n=n+l[i]

    return n
def len_long(midtemp):
    len=0    
    while (midtemp>0):
        midtemp=midtemp/10
        len=len+1
    return len
def eighteen_to_list(midtemp):
    temp=1
    n=[]
    len=len_long(midtemp) 
    while(midtemp>0):
        temp=midtemp%18
        n.append(temp)
        midtemp=midtemp/18
    return n

def list_to_str(arg):
    strn=""
    for i in range(len(arg)):
        if(arg[i]<10 and arg[i]>=0):
            strn=strn+str(arg[i])
        if(arg[i]>=9 and arg[i]<36):
            #ABCD
            n=arg[i]-9
            strn=strn+aplb[n-1]
        if(arg[i]>=36 and arg[i]<62):
            #abcd
            n=arg[i]-36
            strn=strn+apls[n-1]
    return strn
etl= eighteen_to_list(mid)
strshow=list_to_str(etl)
7102eMkcarCeuXnaK
48HB11E144HG147C054EHADE
334476251944397096847543189896

EDAHE450C741GH441E11BH84

还原算法如上,倒是不算太复杂了

  init_key(magicbox);
  strcpy(&v9, "KanXueCrackMe2017");
  v10 = 0;
  keygen((SomeArr *)magicbox, &v9);             
  // magicbox
  // 001E18C0  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  ...........
  // 001E18D0  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
  // 001E18E0  08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00  ..............
  v2 = (_WORD *)v1[38];
  v3 = *((_DWORD *)v2 - 3);
  for ( i = 0; i < v3; ++v2 )
  {
    if ( i < 0 || i > v3 )
      sub_401540(0x80070057);
    input[i++] = *v2;
  }
  input[i] = 0;
  ms_exc.registration.TryLevel = 1;
  keygen((SomeArr *)magicbox, input);
  v5 = 0;
  do
  {
    if ( magicbox[v5] != v8[v5] )

看了一些算法分析的writeup,说是这里是建模建立了个魔方的矩阵。

其实这里如果没有提示,鬼知道什么魔方变换。矩阵操作倒是能看到。
keygen((SomeArr *)magicbox, input);

 // [[4, 3], [4, 2], [3, 2], [5, 3], [4, 3], [1, 2], 
 // [1, 3], [0, 1], [4, 1],[2, 2], [1, 2], [0, 2], 
// [5, 2], [5, 3], [1, 2], [1, 2], [0, 2], [4, 3],
 // [0, 2], [0, 2], [3, 3], [5, 3], [2, 3], [1, 2]]
      mult_arrays_pow(v3 / 3, v3 % 3 + 1, (int)computed);

这里一个大问题是很难分析出矩阵操作的规律,不过既然要对比 if ( magicbox[v5] != v8[v5] )的值让他相等,其实这里关键就是要看v8变化的过程。

00161C90  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
00161CA0  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
00161CB0  08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00  ..............
00161CC0  0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00  ..............
00161CD0  10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00  ............
00161CE0  14 00 00 00 15 00 00 00 16 00 00 00 17 00 00 00  ............
00161CF0  18 00 00 00 19 00 00 00 1A 00 00 00 1B 00 00 00  ............
00161D00  1C 00 00 00 1D 00 00 00 1E 00 00 00 1F 00 00 00  ............
00161D10  20 00 00 00 21 00 00 00 22 00 00 00 23 00 00 00   ...!..."...#...
00161D20  24 00 00 00 25 00 00 00 26 00 00 00 27 00 00 00  $...%...&...'...
00161D30  28 00 00 00 29 00 00 00 2A 00 00 00 2B 00 00 00  (...)...*...+...
00161D40  2C 00 00 00 2D 00 00 00 2E 00 00 00 2F 00 00 00  ,...-......./...
00161D50  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
00161D60  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
00161D70  08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00  ..............
00161D80  0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00  ..............
00161D90  10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00  ............
00161DA0  14 00 00 00 15 00 00 00 16 00 00 00 17 00 00 00  ............
00161DB0  18 00 00 00 19 00 00 00 1A 00 00 00 1B 00 00 00  ............
00161DC0  1C 00 00 00 1D 00 00 00 1E 00 00 00 1F 00 00 00  ............
00161DD0  20 00 00 00 21 00 00 00 22 00 00 00 23 00 00 00   ...!..."...#...
00161DE0  24 00 00 00 25 00 00 00 26 00 00 00 27 00 00 00  $...%...&...'...
00161DF0  28 00 00 00 29 00 00 00 2A 00 00 00 2B 00 00 00  (...)...*...+...
00161E00  2C 00 00 00 2D 00 00 00 2E 00 00 00 2F 00 00 00  ,...-......./...


00161C90  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
00161CA0  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
00161CB0  08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00  ..............
00161CC0  0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00  ..............
00161CD0  10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00  ............
00161CE0  14 00 00 00 15 00 00 00 16 00 00 00 17 00 00 00  ............
00161CF0  18 00 00 00 19 00 00 00 1A 00 00 00 1B 00 00 00  ............
00161D00  1C 00 00 00 1D 00 00 00 1E 00 00 00 1F 00 00 00  ............
00161D10  20 00 00 00 21 00 00 00 22 00 00 00 23 00 00 00   ...!..."...#...
00161D20  24 00 00 00 25 00 00 00 26 00 00 00 27 00 00 00  $...%...&...'...
00161D30  28 00 00 00 29 00 00 00 2A 00 00 00 2B 00 00 00  (...)...*...+...
00161D40  2C 00 00 00 2D 00 00 00 2E 00 00 00 2F 00 00 00  ,...-......./...
00161D50  02 00 00 00 07 00 00 00 12 00 00 00 2F 00 00 00  ........./...
00161D60  16 00 00 00 1F 00 00 00 2E 00 00 00 29 00 00 00  ..........)...
00161D70  1E 00 00 00 0F 00 00 00 00 00 00 00 0D 00 00 00  ..............
00161D80  0A 00 00 00 23 00 00 00 10 00 00 00 11 00 00 00  ....#.........
00161D90  2C 00 00 00 01 00 00 00 0E 00 00 00 05 00 00 00  ,............
00161DA0  24 00 00 00 09 00 00 00 1A 00 00 00 27 00 00 00  $..........'...
00161DB0  08 00 00 00 25 00 00 00 04 00 00 00 2D 00 00 00  ...%......-...
00161DC0  18 00 00 00 13 00 00 00 1C 00 00 00 17 00 00 00  ............
00161DD0  28 00 00 00 0B 00 00 00 0C 00 00 00 1D 00 00 00  (.............
00161DE0  20 00 00 00 03 00 00 00 2A 00 00 00 1B 00 00 00   ......*......
00161DF0  14 00 00 00 2B 00 00 00 06 00 00 00 19 00 00 00  ...+.........
00161E00  22 00 00 00 21 00 00 00 26 00 00 00 15 00 00 00  "...!...&......

这里有两个大块,初始化时是一样的,经过按字符串的一系列变化变成了下面的大块。
通过对寄存器更改观察 mult_arrays_pow(v3 / 3, v3 % 3 + 1, (int)computed);的操作堆这两字符串的更改

经过对【0,1】【0,2】操作数的分析,操作的是如下地址处的数据
00161D50  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
00161D60  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............

06 00 00 00 07 00 00 00 00 00 00 00 01 00 00 00  .............
02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00

00161D50  02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00  ............
00161D60  06 00 00 00 07 00 00 00 00 00 00 00 01 00 00 00  .............

前一个数字代表矩阵代号,后一个数字代表循环移动的长度,1代表移动8.

也就是是说这个大块中有两个数组,第一个数组明显是用来对比变换的,不用分析,第二个数组是重点。分成了6个矩阵。【x,y】堆这几个矩阵进行操作。x代表矩阵编号,y代表矩阵变换。其实变换本身比较简单,就是简单的位移。1代表循环位移8位。

这么说倒是有点像魔方了。不过我感觉魔方变换本身不是难点,倒是这个逆向分析过程才是重点。

上面已经分析过了,原始的魔方数组经过的变换为 [[4, 3], [4, 2], [3, 2], [5, 3], [4, 3], [1, 2], [1, 3], [0, 1], [4, 1],[2, 2], [1, 2], [0, 2], [5, 2], [5, 3], [1, 2], [1, 2], [0, 2], [4, 3],[0, 2], [0, 2], [3, 3], [5, 3], [2, 3], [1, 2]]
要想使魔方还原就要经过逆运算。据说这里有不只一个解。
我们要还原还是要从最后的数据还原

#[[1, 2], [2, 1], [5, 1], [3, 1], [0, 2], [0, 2], [4, 1], [0, 2], [1, 2], 
#[1, 2], [5, 1], [5, 2], [0, 2], [1, 2], [2, 2], [4, 3], [0, 3], [1, 1], 
#[1, 2], [4, 1], [5, 1], [3, 2], [4, 2], [4, 1]]

化简下

[[1, 2], [2, 1], [5, 1], [3, 1],[4, 1], [0, 2], [5, 3], [0, 2], [1, 2], [2, 2], [4, 3], [0, 3],[1, 3], [4, 1], [5, 1], [3, 2], [4, 3]]

3x+y-1

ln=[[1, 2], [2, 1], [5, 1], [3, 1],[4, 1], [0, 2], [5, 3], [0, 2], [1, 2], [2, 2], [4, 3], [0, 3],[1, 3], [4, 1], [5, 1], [3, 2], [4, 3]]
res=[]
for i in ln:
    res.append(3*i[0]+i[1]-1)
print res

[4, 6, 15, 9, 12, 1, 17, 1, 4, 7, 14, 2, 5, 12, 15, 10, 14]

漏洞分析丨HEVD-0x2.StackOverflowGS[win7x86] 视频制作不易,求三联支持,拜谢~添加公众账号“极安御信安全研究院”,报暗号:“资料” 即可领取视频相关工具、源码、学习资料,和其他逆向工程免费课。进交流群报暗号“交流群” 网络安全交流群QQ:434238324... 阅读详情

相关推荐

BUUCTF virink_2019_files_share

BUUCTF virink_2019_files_share 考点: 任意文件读取 双写../绕过过滤 双击开始后,是一个拼魔方的小游戏,进行简单的信息收集,限制了鼠标右键功能,在地址栏前加入view-source:即可,得到提示: <link rel="stylesheet" href="/static/style.css"> <link rel="icon" href="/uploads/favicon.ico" type="image/x-icon" /> <!--

Senimo 1585

SEH 进阶(1)

SHE进阶 了解了上一篇的文章之后,我们写一个简单的例子来验证我们的想法,并学习新的知识。 不同的编译器提供的增强版本SHE 可能不同,但是它们都是基于windows 底层SHE 的。我们使用Win10 1703 + VS2010 生成X86 Rlease 程序来验证已经学过的知识,后面使用XP x86 7600 来学习编译器版本的SHE。 编译如下程序 #define WIN32_LEA

商少 1850

re学习(36)看雪CTF 2017 -Crackme

刚开始用的是IDA分析,分析了半天也没有看出来什么,然后就在网上搜,还真搜出来了,直接上flag,解决了我的燃眉之急,哈哈,事后又看了看wp,才知道了真正的解法,还是应该总结的,毕竟有的题目是搜不到的......3、取key中第2位值为“5”的十六进制值即0x35,然后减去0x30,0x31-0x30 =5 ,接着就是1除以5得出浮点数0.2。,不相同则“error”这里验证key的值是否都为字符串“0”,如果4位的key又一个为“0”,则直接跳转到“error”弹出框。OD反汇编代码可以着色,比较醒目。

m0_66039322的博客 587

反调试技术

思来想去还是先写反反调试,壳的话打算在PE文件内容里写反调试顾名思义就是用尽一切手段防止运行时对程序的非法篡改和窥视,加大代码的复杂度和分析等以下只是遇到的一些反调试,其中有一些知识都没有学习到,不过慢慢来也慢慢补坑。

nareku的博客 1671

字节--旋转魔方

字节–旋转魔方 文章目录字节--旋转魔方一、题目描述二、分析三、代码 一、题目描述 二阶魔方又叫小魔方,是222的立方形结构。每一面都有4个块,共有24个块。每次操作可以将任意一面逆时针或者顺时针旋转90°,如将上面逆时针旋转90°操作如下。 Nero在小魔方上做了一些改动,用数字替换每个块上面的颜色,称之为数字魔方。魔方上每一面的优美度就是这个面上4个数字的乘积,而魔方的总优美度就是6个面优美度总和。 现在Nero有一个数字魔方,他想知道这个魔方在操作不超过5次的前提下能达到的最大优美度是多少。 魔方展

wolfGuiDao的博客 1586

【网络安全 | CTF】攻防世界 backup 解题详析

例如,可以将备份文件的文件名设置为 index_backup.php、index.bak 或 index_php_backup.php 等。例如,如果要备份名为 index.php 的文件,则可以将其备份文件命名为 index_20230521_004017.php。:tar (tape archive) 打包格式和 gzip 压缩算法结合使用的备份文件格式,可以使用 tar 和 gunzip 工具进行解压缩。:纯文本格式,通常不用于表示备份文件,但可以将备份文件的内容存储为文本文件进行备份。

等风来 7923

[Windows] CVE-2011-2005 Afd.sys 本地提权漏洞复现

前言 这是一个微软在2011.10发布的补丁中提到的系统辅助驱动程序Afd.sys存在的本地提权漏洞, 影响到Windows XP, 和Windows Server 2003系统. 漏洞成因是Microsoft Windows Ancillary Function Driver(afd.sys)驱动程序没有完善检测用户提交的数据, 攻击者可以利用该漏洞执行任意代码. 漏洞分析 漏洞利用 总结 ...

fa1c4的blog 3733

[Python] 暴力破解压缩文件zip工具 python 源码 图解教程

当你忘记压缩文件的密码怎么办呢?可以自己写一个暴力破解压缩文件zip的工具, python 源码 提供给大家

2017看雪秋季赛 第五题

先贴一发官方题解https://ctf.pediy.com/game-fight-50.htm从正向出题人的思路考虑,和逆向者的方向考虑这个题,都挺有意思的首先照例先运行加上IDA分析,找特征字符串特征字符串:失败然后找到了函数:406FC3很明显,这里是对常量字符串进行处理这里是一个base64的比较,然后加密解密都尝试下,发现进了死胡同!~使用jump to xref,只有函数4071FD调用...

ACdream 426

CString 初始化 和 函数用法大全.pdf

CString 初始化 和 函数用法大全,各种常见CString用法

登录页面要验证的验证码

登录页面要验证的验证码,希望对你会有所帮助。

NSSCTF刷题笔记web16——[LitCTF 2023]1zjs

然后就想着在每个文件里搜索flag,无果,然后再搜一下有没有php文件的。吐槽一下,和开局的魔方啊,ts啊什么的半毛钱关系没有,想得太复杂了。打开是一段加密后的数据,加密方式叫jsf**k。直接在ctrl+a全部复制到控制台就可以解码。那么先从这个js文件下手吧。这个文件可能是魔方的源代码。ts大概就是js的优化版本。然后啊,然后依然是颗粒无收。打开网页是个3d魔方游戏。再看看三个ts后缀的文件。然后就找到了,直接访问。

qq_45692883的博客 664

二阶魔方_cube_TheProgram_二阶魔方_

a program to solve the cube problem

[山河CTF 2024] week3

拉格朗日插值法 格

weixin_52640415的博客 935

C++ 核电站

问题描述 一个核电站有n个放核物质的坑,排列在一条直线上。如果连续m个坑中放入核物质就会发生爆炸,所以某些坑中不能放核物质。 本题的任务:对于给定的n和m,求不发生爆炸的放置核物质的方案总数。 输入格式 第一行两个正整数n和m,之间用一个空格隔开。2≤n≤50,2≤m≤5。 输出格式 一行一个正整数,表示方案总数。 输入样例 4 3 输出样例 13 数据规模与约定 2≤n≤50,2≤m≤5 CODE #include<bits/stdc++.h> using namespace

HybridCOW_HORSE的博客 1803

Python与西门子PLC数据交互实战:基于Snap7的跨平台工业通信指南

本文详细介绍了如何使用Python和Snap7库实现与西门子PLC的数据交互。内容涵盖跨平台环境搭建、连接参数配置、数据读写实战及性能优化技巧,为工业自动化、数据采集和智能制造场景提供了一套轻量、灵活且高效的通信解决方案。

vim8coder的博客 285

CFreeMarshaler::MarshalInterface逆向结果唯一可以触发CFreeMarshaler::InitSecret的地方

HRESULT __stdcall CFreeMarshaler::MarshalInterface(CFreeMarshaler *this, IStream *pStm, _GUID *riid, void *pv, unsigned int dwDestContext, void *pvDestContext, unsigned int mshlflags) { int v7; // e...

如鹿渴慕泉水的专栏 509

MTGS与3D高斯泼溅:如何用多轨迹数据重建自动驾驶场景(附代码解析)

本文深入解析了MTGS(多轨迹高斯泼溅)技术在自动驾驶场景重建中的工程实践。该方法通过分层场景表示,巧妙融合多轨迹数据,利用3D高斯泼溅技术统一处理静态几何与动态物体,有效解决了复杂环境下的重建难题。文章结合代码,详细阐述了其实现框架、损失函数设计及优化策略,为构建高保真数字孪生场景提供了实用指南。

v5w6x的博客 446

C++反汇编与逆向之识别main函数学习笔记

int main(int argc, char* argv[]) { // main(int 1, char * * 0x00380d70) line 7 // mainCRTStartup() line 206 + 25 bytes // KERNEL32! 7c817067() // 根据堆栈的先进后出原则可知 // 程序在调用main函数之前,先调用了Kernel32 ->

AvinLi的专栏 1259

MMSegmentation 安装教程,避免mmcv不合适版本,及相关问题解决

都行,不做要求。

qq_43683133的博客 1220

汇川AM系列PLC玩转CNC:手把手教你用File模式读取G代码文件(附避坑指南)

本文详细介绍了如何使用汇川AM系列PLC的File模式读取G代码文件,涵盖从CAD设计到PLC配置的全流程。特别针对路径格式、文件类型等常见问题提供避坑指南,帮助工程师快速实现CNC加工的自动化控制。

weixin_33582311的博客 406

西湖论剑2021

西湖论剑RE部分题解

qq_52974719的博客 494

基于SOLIDWORKS API的工业级插件开发指南

SOLIDWORKS API是基于COM技术的一套开发接口,支持C#、VB.NET等语言,用于自动化建模、属性管理、界面定制等功能。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 2749

攻防世界(web区,难度1,5道题)nssctf(web区,4道题)

file1=php://filter/convert.base64-encode/resource=flag.php&file2=data://text/plain,hello ctf”,得到一串字符。3.那么就可以用伪协议php://filter,在Cookies的框中输入“language=php://filter/convert.base64-encode/resource=flag”,得到一串字符。2.在URL后加上“/?2.根据提示,在URL后加上“/robots.txt”,得到下一步的提示。

weixin_74347680的博客 886

【异常】Openclaw Gateway进程异常停止问题分析与解决方案

本文分析了Gateway服务异常停止的问题,提出了三种解决方案。核心问题是缺乏进程守护和自动恢复机制,导致服务崩溃后无法自行重启。推荐方案是使用PM2进程管理工具(方案1),提供进程监控、自动重启和开机自启功能。替代方案包括自定义守护脚本(方案2)和supervisord管理(方案3)。这些方案都能有效解决当前服务脆弱性问题,显著提升服务可用性,其中PM2方案成熟度高、配置简单,是首选解决方案。实施后可将服务从人工干预转变为自动恢复,确保业务连续性。

奶爸的编程之路,也就一周冷个三天 457

R语言coxph函数对加权数据集进行竞争风险模型拟合、regplot包的regplot函数可视化竞争风险回归模型的列线图nomogram、计算特定病例的事件概率(控制了竞争风险的累计事件概率)

R语言coxph函数对加权数据集进行竞争风险模型拟合、regplot包的regplot函数可视化竞争风险回归模型的列线图nomogram、计算特定病例的事件概率(控制了竞争风险的累计事件概率)

statistics+insight+vista+power 359
上一篇: ios http数据请求小结
下一篇: dalvik虚拟机启动及运行
inquisiter
博客等级 码龄10年 374粉丝 228原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值