C 语言栈溢出示例:无限递归与循环数字序列
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 -> ...
这是一个无限循环的数字序列。
解释:
kGotoTable数组包含 1024 个整数,每个整数都对应一个索引值(从 0 到 1023)。triggerStackOverflow函数接收一个整数value,并递归调用自身,使用kGotoTable[value]获取新的索引值。- 当输入
number为 42 时,triggerStackOverflow(42)开始递归调用,并依次访问kGotoTable[42]、kGotoTable[kGotoTable[42]]等索引值,形成一个数字序列。 - 由于
kGotoTable数组中存在循环,当访问到某个重复出现的数字时,就会进入无限递归循环。
栈溢出风险:
当递归调用次数过多时,程序可能会导致栈溢出。栈是一个内存区域,用于存储函数调用信息(例如参数、局部变量、返回值地址等)。当递归调用次数过多时,栈空间会被耗尽,从而导致程序崩溃。
避免栈溢出:
- 使用迭代方式代替递归。
- 限制递归深度。
- 使用尾递归优化,将递归调用转换为循环。
总结:
本文通过一个 C 语言程序示例展示了栈溢出攻击的原理,并分析了当输入为 42 时,triggerStackOverflow 函数中的无限递归所产生的循环数字序列。这提醒我们,在编写程序时要警惕递归调用次数过多造成的栈溢出风险,并采取相应的措施来避免它。
原文地址: http://www.cveoy.top/t/topic/S7I 著作权归作者所有。请勿转载和采集!