C 语言栈溢出示例:无限递归与循环数字序列

以下代码展示了一个简单的 C 语言程序,它通过无限递归的方式模拟了栈溢出攻击:

#include <stdio.h>
#include <stdlib.h>

int kGotoTable[1024] = {
    456,  841,  205,  326,  999,  935,   16,  497,  825,  218,  719,  204,  722,  792,  889,  779,  195, 1008,  776,  834,  587,  652,  498,  973,  428,  676,  876,  148,  126,  374,  190,   76,
    530,  994,  898,  806,   75,  865,   30,  863,   36,  167,    7,  414,  496,  391,  103,  111,  679,   35,  953,   65, 1013,   45,  263,  736,  760,  648,  983,   78,  626,   83,  571,  595,
        73,  877,  887,  666,  319,  275,  443,    9,  646,  257,  746,  526,  163,   53,    6,  726,   51,  485, 1014,  665,  738,  198,  493,  337,  761,  971,   31, 1009,   88,  325,  151,  177,
    1007,  466,  988,  897,  644,  696,  630,  998,  193,  924,  769,  459,  107,  710,  519,  281,  390,  934,  632,  297,  484,  554,  314,  949,   47,   87,  400,  900,  931,  856,  470,   81,
    191,  101,  780,  342,   82,  693,  528,  701,  499,  164,  671,  181,  395,   34,  481,  614,  547,  478,  588,   43,  673,  440,  258,  568,  196,  790,  479,  844,  728,  365,  896,  868,
    592,  283, 1000,  720,  685,  913,  387,  527,  796,  583,   79,   13,  334,  805,  929,  921,  610,  521,  364,  791,  253,  811,  773,  309,  637,  749,  421,  942,  729,  694,  940,  122,
    393,  525, 1012,   74,  559,  371,  869,   12,  581,   24, 1011,  327,  681,  893,  835,  704,   62,  492,  293,  389,  977,  429,  458,  357,  347,  129,  274,  222,   23,  851,  301,  578,
        70,  550,  946,  797,    2,  882,   40,  923, 1017,  885,  173,  462,  133,  329,  503,  997,  402,  359,   32,  132,  970,  185,  490,  225,  565,   28,  843,  510,  223,  707,  532,  338,
        64,  154,  627,  483,  700,  697,  477,  545,  937,  702,    5,  494,  705,  926,  596,   22,  143,  118,  202,  169,  854,  939,  867,  188,  212,  145, 1021,  830,  114,  833,  316,  925,
    649,  708,  838,  373,  216,  658,   77,  757,  340,  514,  339,  380,  593,  403,  566,  230,  981,  616,  174,  277,  706,   71,  640,  352,  576,  460,   14,  333,  574,   46,  793,  131,
    439,  692,  123,  376,   52,  457,   99,  549,   27,  713,  320,  752,  147,  775,   89,  961,  384,   38,  672,  142,  135,   97,  589,  157,  699,  430,  635,  287,  846,  817,  995,  422,
    758,  209,  991,  801,  300,  434,  562,  323,  546,  860,  450,  121,  812,  563,  905, 1006,  611,  508,  774,  310,  754,  990,  798, 1005,  271,  954,  770,  426,  500,  883,  660,  467,
        67,  920,  886,  161,  687,  584,  409,  141,  350,  711,  410,  698,  245,  482,  535,  351,  511,  986,  515,  659,  778,  955,  264,  331,  911,  267,  189,  231,  162,  594,  788,  782,
    794,  677,  747,  814,  399,  992,  468,   18,  850,  891,  144,  582,  343,  522,  613,   92,  839,  168,  909,   93,  933,  972,  247, 1004,  739,  115,  654,  454,  534,  906,  907,  695,
    819,  802,  591,  406,  227,   37,  290,  194,  404,   41,   20,  888,  918,  941,  601,  771,  480,  826,  488,   68,  952,  232,  255,  269,  871,  307,  762,  378,  600,  237,  899,  849,
    932,  413,  980,  186,  950,  651,  415,  645,  784,    0,  551,  725,  670,  661,  930,  721,  564,  620,  233,  317,  197,  976,  242,   44,  506,  433,    1,  140,  318,  328,   95,  653,
    464,  292,  249,  423,  146,  254,  299,   54,  213,  996,   21,  200,  948,  446,  149,  741,  866,  870,  878,  624,  285,  416,  507,  279,  647,  612,  455,  767,  602,   58,   42,  786,
    974,  447,  282,  354,  742,  137,  727,  407, 1002,  915,  348,  539,  385,  335,  236,  912,  577,  689,  813,  958,  628,  548,  124,  884,  179,   26,  605,  465,  951,  171,  441,  420,
    418,  502,  718,  987,  531,  716,  243,  211,   94,  822,  358,   56,  982,  541,  842,  452,  268,  353,  435,  408,  895,  730,   90,  816,  669,  759,  117,  240,  743,  288,  251,  638,
    542,  927,  824,  270,   80,  618,  379,  857, 1019,  967,  278,   39,   15,  853,  375,  308,  208,  349,  960,  158,  425,  524,  294,  703,  228,  733,  445, 1022,  709,  615,  787,  266,
    804,  680,  453,  262,  968,  295,  621,  712,  210,  803,  280,   98,  303,  105,  362,  682,  377,  401,  807,  370,   86,  489,  139,  963,  463,  643,  943,  155,  113,  772,  538,  127,
    599,  634,  633,  567,  715,   50,  663,  206,  427,   29,  112,  523,  272,  203,  845,  346,  580,  956,  229,  902,  777,    3,  109,  650,  381,  674,  872,  558,  723,  737,  472,  892,
    664,   10,  827,   17,  631,  286,  607,  265,  207,  336,  215,  572,  984,  182,  947,  916,  848,  609,  248,  914,  363,  486,  604,   33,  261,  684,  315, 1001,  569,  852,  432,  586,
    537,  516,   57,   60,  160,  120,  110,  556,  517,  656,  306,  451,  509,  298,  642,  828,  745,  629,   66,   96,   84,  361, 1003, 1020,  180,  276,  667,  166,   72,  394,  904,  219,
    192, 1010,  321,  688,  224,  259,  691,  405,  382,  178,  964,  544,  585,    4,  220,  879,  732,  832,  978,  606,  104,  910,  809,  100,  799,  862,  861,  431,  890,  199,  324,  360,
        49,  183,  471,  138,  617,  244,  847,  449,  529,   61,  768,  800,  969,  505,   11,  234,  102,  625,  836,  756,  678,  875,  573,  125, 1016,  683,  579,  312,  962,  473,  152,  686,
    273,  740,  150,  201,  136,  821,  355,  724,  859,  116,  461,  858,  397,  881,  570,   55,  134,  388,  755,  332,  356,  438,  221,   85,  386,  979,  831,  226,  873,  396,  789,  945,
    655,  763,  424,  330,  476,  170,  444,  748,  557,  561,  823,  657,  908,  553,  985,  735,  469,  619,  304, 1018,  130,  781,  874,   69,   48,  810,  598,  957,  217,  345,  623,  734,
        59,  936,  322,  106,  690,  829,  785,  305,  917,  383,  296,  989,  487,  555,  668,  820,  520,  837,  518,  491,   91,  714,  540,  543,  608,  903,   25,  284,  159,  501,  367,  765,
        19,  864,  959,  675,  536,  641,  241,  411,  214,  256,  419,  250,  344,  153,  176,  437,  764,  944,  880, 1015,  165,  840,  108,  533,  965,  235,  815,  442,  302,  291,  922,  560,
    753,  750,  260,  993,  475,  172,  639,  369,  590,  938,  855,  238,  504,  184,  119,  368,  448,  744,  975,  928,  603,  128,  795,  187,  436, 1023,  552,  808,  783,  398,  662,  622,
    311,  372,  392,  513,  289,  366,  495,  474,  597,  246,  417,  575,  894,  512,  717,  731,  751,  313,  252,  175,  966,  412,  636,  818,  239,  766,  341,   63,  901,  919,  156,    8,
};

void shuffleValues(int arr[], int count)
{
	srand(0);
    const unsigned int  magic = 100;
    for (unsigned int j = 0; j < magic; j++) {
	    for (int i = 0; i < count - 1; i++)
	    {
		    int num = i + rand() % (count - 1 - i);
		    int temp = arr[i];
		    arr[i] = arr[num];
		    arr[num] = temp;
	    }
    }
}

void triggerStackOverflow(int value) {          triggerStackOverflow(kGotoTable[value]);
}

int main(void) {
    int number;
    printf("What is your favorite number from 0 to 1023?
");
    // 如果嫌太烦了建议使用数字42
    scanf("%d", &number);
    while (number < 0 || number > 1023) {
        printf("Oops!You played a joke on me.Please give me a number from 0 to 1023.");
        scanf("%d", &number);
    }
    shuffleValues(kGotoTable, 1024);
    triggerStackOverflow(number);
    return EXIT_SUCCESS;
}

当输入的 number 值为 42 时,找出 triggerStackOverflow 函数无限递归中,周期循环的一组数字内容:

根据提供的代码,当输入的 number 值为 42 时,触发无限递归的一组数字为:

739 -> 287 -> 846 -> 817 -> 995 -> 422 -> 758 -> 209 -> 991 -> 801 -> 300 -> 434 -> 562 -> 323 -> 546 -> 860 -> 450 -> 121 -> 812 -> 563 -> 905 -> 1006 -> 611 -> 508 -> 774 -> 310 -> 754 -> 990 -> 798 -> 1005 -> 271 -> 954 -> 770 -> 426 -> 500 -> 883 -> 660 -> 467 -> 67 -> 920 -> 886 -> 161 -> 687 -> 584 -> 409 -> 141 -> 350 -> 711 -> 410 -> 698 -> 245 -> 482 -> 535 -> 351 -> 511 -> 986 -> 515 -> 659 -> 778 -> 955 -> 264 -> 331 -> 911 -> 267 -> 189 -> 231 -> 162 -> 594 -> 788 -> 782 -> 794 -> 677 -> 747 -> 814 -> 399 -> 992 -> 468 -> 18 -> 850 -> 891 -> 144 -> 582 -> 343 -> 522 -> 613 -> 92 -> 839 -> 168 -> 909 -> 93 -> 933 -> 972 -> 247 -> 1004 -> 739 -> ...

这是一个无限循环的数字序列。

解释:

  1. kGotoTable 数组包含 1024 个整数,每个整数都对应一个索引值(从 0 到 1023)。
  2. triggerStackOverflow 函数接收一个整数 value,并递归调用自身,使用 kGotoTable[value] 获取新的索引值。
  3. 当输入 number 为 42 时,triggerStackOverflow(42) 开始递归调用,并依次访问 kGotoTable[42]kGotoTable[kGotoTable[42]] 等索引值,形成一个数字序列。
  4. 由于 kGotoTable 数组中存在循环,当访问到某个重复出现的数字时,就会进入无限递归循环。

栈溢出风险:

当递归调用次数过多时,程序可能会导致栈溢出。栈是一个内存区域,用于存储函数调用信息(例如参数、局部变量、返回值地址等)。当递归调用次数过多时,栈空间会被耗尽,从而导致程序崩溃。

避免栈溢出:

  1. 使用迭代方式代替递归。
  2. 限制递归深度。
  3. 使用尾递归优化,将递归调用转换为循环。

总结:

本文通过一个 C 语言程序示例展示了栈溢出攻击的原理,并分析了当输入为 42 时,triggerStackOverflow 函数中的无限递归所产生的循环数字序列。这提醒我们,在编写程序时要警惕递归调用次数过多造成的栈溢出风险,并采取相应的措施来避免它。

C 语言栈溢出示例:无限递归与循环数字序列

原文地址: http://www.cveoy.top/t/topic/S7I 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录