• XSS.stack #1 – первый литературный журнал от юзеров форума

Хитрый буфер?

Encommerce

(L3) cache
Пользователь
Регистрация
25.11.2022
Сообщения
235
Реакции
97
В общем пытаюсь реализовать чтение файла с возможостью устанавливать пропуск шага


Код:
let payload_freq= 5; // Одно выполнение на 5 итераций цикла

let mut reader = BufReader::new(file);
let mut writer = BufWriter::new(output);

let mut buffer = vec![0u8; BUFFER_SIZE].into_boxed_slice();
let mut count: usize;

loop {
    count = reader.read(&mut buffer)?;

    if count == BUFFER_SIZE {
        ...
        if (пятая итерация) {
            println!("payload...");
        }
    } else {
        ...
        if (пятая итерация) {
            println!("payload...");
        }
    }
}


Что-то вроде:
> читаем
> читаем
> читаем
> читаем
> читаем и что-то делаем
> читаем
> читаем
> читаем
> читаем
> читаем и что-то делаем
...

Неуверен, что нормально объяснил)

Может сталкивался кто?
 
Сделай счётчик циклов, и проверяй с помощью оператора остатка от деления (%). В C примерно так:

C:
for (int i = 0;; i++) {
    // ...
    
    if (i && i % 5 == 0)
    {
        // выполнить действие для 5-й итерации
    }
}
 
Сделай счётчик циклов, и проверяй с помощью оператора остатка от деления (%). В C примерно так:

C:
for (int i = 0;; i++) {
    // ...
   
    if (i && i % 5 == 0)
    {
        // выполнить действие для 5-й итерации
    }
}
В общем вопрос под веществами писал (шутка). Понятно, что можно сделать счетчик любой сложности и использовать его. Честно говоря, порой смотрю свои темы и удивляюсь)

Хотя в целом вопрос-то интересный, только сформулировать его в другом ключе нужно.
В конечном итоге он должен был звучать как-то так:
Какие могут быть оптимизации при интенсивном использовании IO?

Однако, лично для меня, это уже не очень актуально.
За этот месяц поиграл с размерами буффера, пропусками блоков чтения, мапами прочтенных байтов и т.д. В целом, за счет различных оптимизаций, в первую очередь наиболее очевидных (нормальная аллокация памяти, правильно настроенное шифроавние, ...) удалось сильно сместить баланс нагрузки именно в сторону IO.

Так что теперь вопросы звучат так:
Как сбалансировать нагрузку между физическими дисками?
Как сделать более качественную выборку таргетов, дабы не тратить драгоценное время на обработку мусора?
Как реализовать частичное шифрование, не убив при этом криптографию?

На каждый из этих вопросов можно дать множество ответов, от самых очевидных до неординарных)

Так что если есть у кого-то мысли, с радостью послушаю и поделюсь своими
 
Раст:
Как сбалансировать нагрузку между физическими дисками?
Код:
use std::fs::{File, OpenOptions};
use std::io::{BufReader, BufWriter, Read, Write};
use std::sync::Arc;

const BUFFER_SIZE: usize = 1024;

fn main() -> Result<(), std::io::Error> {
    // Open input and output files
    let input_file = File::open("input.txt")?;
    let output_file = OpenOptions::new()
        .write(true)
        .create(true)
        .truncate(true)
        .open("output.txt")?;

    // Create multiple writers, one for each physical disk
    let num_writers = 4;
    let mut writers = Vec::new();
    for _ in 0..num_writers {
        let writer = Arc::new(BufWriter::new(File::create("disk.txt")?));
        writers.push(writer);
    }

    // Read data from input file and stripe it across writers
    let mut buffer = vec![0u8; BUFFER_SIZE].into_boxed_slice();
    let mut count: usize;
    let mut writer_index = 0;
    loop {
        count = input_file.read(&mut buffer)?;

        if count == BUFFER_SIZE {
            // Write to current writer and move to next writer
            writers[writer_index].write_all(&buffer)?;
            writer_index = (writer_index + 1) % num_writers;

            if writer_index == 0 {
                // Execute payload after every 5th iteration
                println!("payload...");
            }
        } else {
            // Write remaining data to current writer
            writers[writer_index].write_all(&buffer[..count])?;
            break;
        }
    }

    // Flush and close writers
    for writer in writers {
        writer.flush()?;
        writer.into_inner()?.sync_all()?;
    }

    Ok(())
}
Как сделать более качественную выборку таргетов, дабы не тратить драгоценное время на обработку мусора?
Код:
let payload_freq = 5; // One execution for 5 loop iterations
let target_data = b"target_data"; // Define the target data to search for

let mut reader = BufReader::new(file);
let mut writer = BufWriter::new(output);

let mut buffer = vec![0u8; BUFFER_SIZE];
let mut count: usize;

loop {
    count = reader.read(&mut buffer)?;

    // Check if the buffer contains the target data
    let target_index = buffer.windows(target_data.len()).position(|w| w == target_data);
    if let Some(idx) = target_index {
        // Found target data, write the buffer up to the target position to output
        writer.write_all(&buffer[..idx + target_data.len()])?;

        // Move the remaining data to the beginning of the buffer
        let remaining_data = count - (idx + target_data.len());
        if remaining_data > 0 {
            buffer.copy_within(idx + target_data.len().., 0);
            count = remaining_data;
        } else {
            break;
        }
    } else {
        // No target data, write the entire buffer to output
        writer.write_all(&buffer[..count])?;
    }

    // Check if it's time for payload execution
    if payload_freq > 0 && count % (payload_freq * BUFFER_SIZE) == 0 {
        println!("payload...");
    }
}
Как реализовать частичное шифрование, не убив при этом криптографию?
АЕС
Код:
use rand::{Rng, SeedableRng};
use rand::rngs::StdRng;
use aes::Aes128;
use block_modes::block_padding::Pkcs7;
use block_modes::{BlockMode, Cbc};
use std::io::{Read, Write};
use std::io::{BufReader, BufWriter};

const BUFFER_SIZE: usize = 4096;

// Encrypt the given data using AES-128 CBC with a random IV
fn encrypt(data: &[u8], key: &[u8]) -> Vec<u8> {
    let mut rng = StdRng::from_entropy();
    let iv: [u8; 16] = rng.gen();
    let cipher = Cbc::<Aes128, Pkcs7>::new_var(key, &iv).unwrap();
    let mut encrypted_data = cipher.encrypt_vec(data);
    encrypted_data.splice(0..0, iv.iter().cloned());
    encrypted_data
}

// Decrypt the given data using AES-128 CBC with the provided IV and key
fn decrypt(data: &[u8], key: &[u8]) -> Vec<u8> {
    let iv = &data[..16];
    let data = &data[16..];
    let cipher = Cbc::<Aes128, Pkcs7>::new_var(key, iv).unwrap();
    cipher.decrypt_vec(data).unwrap()
}

fn main() -> std::io::Result<()> {
    let key = b"my secret key that should be kept safe";

    let mut reader = BufReader::new(file);
    let mut writer = BufWriter::new(output);

    let mut buffer = vec![0u8; BUFFER_SIZE].into_boxed_slice();
    let mut count: usize;
    let mut encrypted_buffer = Vec::new();

    loop {
        count = reader.read(&mut buffer)?;

        if count == BUFFER_SIZE {
            // Encrypt the entire buffer
            encrypted_buffer = encrypt(&buffer, key);
            writer.write_all(&encrypted_buffer)?;

            if payload_freq > 0 && count % payload_freq == 0 {
                println!("payload...");
            }
        } else {
            // Encrypt only the valid part of the buffer
            let encrypted_data = encrypt(&buffer[..count], key);

            // Write the encrypted data to the output
            writer.write_all(&encrypted_data)?;

            if payload_freq > 0 && count % payload_freq == 0 {
                println!("payload...");
            }
        }
    }
}

С:

Как сбалансировать нагрузку между физическими дисками?
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BLOCK_SIZE 4096 // block size in bytes
#define NUM_DISKS 2 // number of physical disks

typedef struct {
    FILE *fp;
    int offset;
} Disk;

Disk disks[NUM_DISKS]; // array of disk objects

int main(int argc, char **argv) {
    // open the files and initialize the disk objects
    for (int i = 0; i < NUM_DISKS; i++) {
        char filename[256];
        sprintf(filename, "disk%d.txt", i);
        FILE *fp = fopen(filename, "wb");
        disks[i].fp = fp;
        disks[i].offset = 0;
    }

    // read from input file and write to disks in a striped pattern
    FILE *input_fp = fopen("input.txt", "rb");
    int i = 0;
    while (!feof(input_fp)) {
        char buffer[BLOCK_SIZE];
        int bytes_read = fread(buffer, sizeof(char), BLOCK_SIZE, input_fp);
        if (bytes_read > 0) {
            fwrite(buffer, sizeof(char), bytes_read, disks[i].fp);
            disks[i].offset += bytes_read;
            i = (i + 1) % NUM_DISKS; // increment i in a cyclic pattern
        }
    }

    // close the files
    fclose(input_fp);
    for (int i = 0; i < NUM_DISKS; i++) {
        fclose(disks[i].fp);
    }

    return 0;
}
Как сделать более качественную выборку таргетов, дабы не тратить драгоценное время на обработку мусора?
C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define BUFFER_SIZE 1024

int main() {
    int payload_freq = 5; // One execution for 5 loop iterations

    FILE* file = fopen("input.txt", "r");
    FILE* output = fopen("output.txt", "w");

    char buffer[BUFFER_SIZE];
    size_t count;

    srand(time(NULL)); // Initialize random number generator

    for (int i = 1; ; i++) {
        count = fread(buffer, 1, BUFFER_SIZE, file);

        if (count == 0) {
            break;
        }

        // Execute payload on random iteration
        if (i % payload_freq == rand() % payload_freq) {
            printf("payload...\n");
        }

        fwrite(buffer, 1, count, output);
    }

    fclose(file);
    fclose(output);

    return 0;
}
Как реализовать частичное шифрование, не убив при этом криптографию?
пример с Чачей
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sodium.h>

#define BUFFER_SIZE 1024

int main(int argc, char *argv[]) {
    if (sodium_init() == -1) {
        exit(EXIT_FAILURE);
    }

    const char *input_file = "input_file";
    const char *output_file = "output_file";
    const int payload_freq = 5;

    // Open input and output files
    FILE *input = fopen(input_file, "rb");
    if (!input) {
        printf("Unable to open file: %s\n", input_file);
        exit(EXIT_FAILURE);
    }

    FILE *output = fopen(output_file, "wb");
    if (!output) {
        printf("Unable to open file: %s\n", output_file);
        exit(EXIT_FAILURE);
    }

    // Initialize stream cipher key and nonce
    unsigned char key[crypto_stream_chacha20_KEYBYTES];
    unsigned char nonce[crypto_stream_chacha20_NONCEBYTES];
    randombytes_buf(key, sizeof(key));
    randombytes_buf(nonce, sizeof(nonce));

    // Write key and nonce to output file
    fwrite(key, 1, sizeof(key), output);
    fwrite(nonce, 1, sizeof(nonce), output);

    // Initialize stream cipher
    crypto_stream_chacha20_xor_ic_state state;
    crypto_stream_chacha20_xor_ic_init(&state, nonce, 0, key);

    // Allocate buffer for reading and encrypting data
    unsigned char buffer[BUFFER_SIZE];

    // Read input file and encrypt every payload_freq-th iteration of the loop
    size_t count;
    int iteration = 0;
    while ((count = fread(buffer, 1, BUFFER_SIZE, input)) > 0) {
        if (++iteration % payload_freq == 0) {
            crypto_stream_chacha20_xor_ic(&state, buffer, buffer, count, 0, nonce);
            fwrite(buffer, 1, count, output);
            printf("payload...\n");
        } else {
            fwrite(buffer, 1, count, output);
        }
    }

    // Clean up
    fclose(input);
    fclose(output);

    return 0;
}

Возможно что-то упустил, прошу не кидать камнями
 
Спасибо за ответ. Я расчитывал просто поболтать, в тут 2км кода :)

Это все, к сожелению, не то. Надеюсь это писал chat gpt хотя бы)

Проблему с дисками более подробно тут описал:
https://xss.pro/threads/82918/
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх