Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
pico2-swd-riscv — Biblioteca de probe de depuração SWD para núcleos RP2350 RISC-V. Fornece halt/resume/step, acesso a registradores e memória, execução de código e rastreamento de instruções através de dois fios GPIO usando bit-banging PIO. | Kitploit
Ferramentas/GitHubGitHub/jackdoe/pico2-swd-riscv
Segurança de Sistemas EmbarcadosEngenharia ReversaDepuradoresHacking de HardwareSegurança de HardwareAnálise de Firmware
GitHubjackdoe/pico2-swd-riscv

pico2-swd-riscv

Biblioteca de probe de depuração SWD para núcleos RP2350 RISC-V. Fornece halt/resume/step, acesso a registradores e memória, execução de código e rastreamento de instruções através de dois fios GPIO usando bit-banging PIO.

Ver Repositório
8534há 7 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

pico2-swd-riscv

Sonda de depuração SWD para núcleos RP2350 RISC-V (Hazard3). Um Pico2 depura outro através de dois fios GPIO.

0. AVISO DE VIBE CODE (ESCRITO POR HUMANO)

Cerca de 80% do código é vibe coded; o readme é quase totalmente gerado (exceto toda a seção de aviso de vibe code). Passei muitas noites com o osciloscópio e a documentação e fiz um protótipo funcional que conseguia fazer sba/ler/escrever registradores e executar comandos abstratos e progbuf, o resto foi feito com claude code. Os testes são bastante abrangentes (comprehensive test suite) e uso o núcleo da biblioteca nos meus próprios projetos, mas, como dizem, "hic sunt dracones". Também li o readme e o código e não notei nada de errado (e removi as partes erradas/confusas).

Este projeto foi meu estudo de caso de vibecoding de um projeto mais complicado que não entendo 100% e não há código existente óbvio que possa ser "usado". Começou como ~1000 linhas de código que eu mesmo escrevi e conhecia muito bem, lendo os documentos do rp2350, arm swd e riscv debug, capturando dados com osciloscópio e openocd, depois decodificando e analisando a sequência de wakeup e depois comandos de leitura/escrita. Depois que consegui fazer funcionar, entreguei ao claude para transformá-lo em uma biblioteca que eu pudesse usar em outros projetos, e então fui construindo lentamente.

Depois de cerca de 3‑4k linhas de código, perdi completamente o controle do que estava acontecendo, e não consideraria este código como algo que escrevi, mas adicionar mais e mais testes parecia "legal", ou pelo menos reconfortante.

Houve um certo gaslighting, particularmente quando ele entendeu mal o dap_read_mem32 pensando que estava lendo da RAM e não o protocolo MEM‑AP TAR/DRW/RDBUFF, o que levou a uma quantidade incrível de bobagem.

No geral, diria que foi uma experiência horrível, mesmo tendo levado 10 horas para escrever quase 10000 linhas de código, não considero este meu projeto, e não tenho nenhum senso de realização ou crescimento.

Em contraste, usar IA para ler toda a documentação (que são milhares de páginas) e escrever scripts úteis para decodificar os dados do osciloscópio, criar structs C compactadas a partir dos documentos, etc., foi muito bom, e me senti bem depois. No momento em que li o primeiro registrador e depois quando consegui ler memória via SBA, me senti incrível.

O principal problema é o "taste" (bom senso), quando escrevo código sinto se é bom ou ruim, enquanto escrevo, sei se está errado, mas usando claude code fico dessensibilizado muito rapidamente e simplesmente não consigo distinguir, ele "parece" OK, mas não sei como "se sente". Neste caso, aconteceu quando o código cresceu cerca de 4x, de 1k para 4k linhas. E pior de tudo, meu modelo mental do código desapareceu completamente, e junto com ele minha propriedade (ownership).

Os tokens não têm razão ou propósito, o que torna a leitura do código ridiculamente difícil, pois cada token pode ser completo absurdo. Ao ler código humano, os símbolos têm um propósito, alguém pensou "Vou colocar isso em uma variável, depois verificarei seu status.", então finjo que sou eles e penso por que eles teriam escrito isso? Logo depois entendo, pois são humanos e eu sou humano. Mas os símbolos da IA não têm razão, e pior de tudo, todos parecem enganosamente corretos, então tenho que pensar 10 vezes mais se está errado. Com qualquer código humano (incluindo o seu próprio), é bastante fácil avaliar o quanto você pode confiar nele, e é bastante consistente; com o código de IA, uma função pode ser muito melhor do que você teria escrito, e o código 2 linhas abaixo pode ser gunk de cargo cult que parece incrivelmente bom, mas está estruturalmente errado.

No final, diria que ganhei um bom entendimento dos fios, temporizações e da mecânica de baixo nível de ap/dp, sba e progbuf, mas me arrependo de não ter escrito tudo sozinho, mesmo que tivesse levado 10x mais tempo.

Eu odeio isso pra caramba.

E não consigo evitar, mas sentir nojo e vergonha. É isso que a programação é agora? Espero muito que isso seja algum estágio intermediário e que mude para melhor, o problema é que não sei o que é "melhor", parece que para alguns é não escrever o código, para outros é não modelar o problema e para terceiros é não precisar pensar. Para mim, não tenho certeza, quero fazer coisas, e muitas vezes não quero saber algo, mas quero usá-lo, por exemplo, o controlador de host USB rp2350, a forma como você tem que rearmar interrupções e a forma como o registrador epx é compartilhado é super irritante, por boas razões provavelmente, mas eu só quero usá-lo para fazer meu driver CBI.

Acho que a pergunta é: o que é a coisa que quero fazer? Porque você pode subir a pilha, desde os registradores do chip USB até CBI, UFI, FAT16, o sistema operacional do computador old school que estou fazendo, mas por que parar? fazer os esquemáticos, as PCBs, os arquivos CAD, talvez enviar automaticamente para a fábrica? e depois apenas enviar para mim? mas por que parar? fazer minha loja online, começar a vender, criar uma comunidade, anúncios, marketing, gerar alguns vídeos de unboxing, talvez alguns memes virais? processar os pedidos diretamente para a fábrica, sob demanda, se houver um problema, está pronto com suporte ao cliente.

O que eu faço enquanto isso? Sentar na praia? Odeio a praia.

Onde isso para?

PS: como disse o poeta: o preço de conseguir o que você quer, é conseguir o que você uma vez quis.

Arquitetura

root@kitploit:~
Application
    |
rp2350.c    RISC-V Debug Module (halt/resume/step, registers, memory, trace)
    |
dap.c       Debug Access Port (DP/AP registers, bank caching, MEM-AP)
    |
swd_protocol.c  SWD wire protocol (PIO bit-banging, packet encoding, retry)
    |
swd.pio     PIO state machine (4-cycle SWCLK, bidirectional SWDIO)

Cada camada mantém seu próprio estado e se comunica apenas com seu vizinho.

Uso

root@kitploit:~
swd_config_t config = swd_config_default();
config.pin_swclk = 2;
config.pin_swdio = 3;

swd_target_t *target = swd_target_create(&config);
swd_connect(target);
rp2350_init(target);

rp2350_halt(target, 0);
swd_result_t pc = rp2350_read_pc(target, 0);
rp2350_resume(target, 0);

swd_target_destroy(target);

Controle de Hart

root@kitploit:~
rp2350_halt(target, 0);
rp2350_step(target, 0);
rp2350_resume(target, 0);
rp2350_reset(target, 0, true);

swd_result_t pc = rp2350_read_pc(target, 0);
rp2350_write_pc(target, 0, 0x20000000);

swd_result_t val = rp2350_read_reg(target, 0, 5);
rp2350_write_reg(target, 0, 5, 0xDEADBEEF);

uint32_t regs[32];
rp2350_read_all_regs(target, 0, regs);

swd_result_t csr = rp2350_read_csr(target, 0, 0x300);
rp2350_write_csr(target, 0, 0x300, value);

Ambos os harts (0 e 1) são controláveis independentemente.

Acesso à Memória

Não intrusivo via Acesso ao Barramento do Sistema (System Bus Access). Funciona enquanto o hart está em execução.

root@kitploit:~
swd_result_t val = rp2350_read_mem32(target, 0x20000000);
rp2350_write_mem32(target, 0x20000000, 0xDEADBEEF);

rp2350_read_mem16(target, addr);
rp2350_write_mem8(target, addr, byte);

uint32_t buf[256];
rp2350_read_mem_block(target, 0x20000000, buf, 256);
rp2350_write_mem_block(target, 0x20000000, buf, 256);

Transferências em bloco usam auto‑incremento SBA para desempenho.

Execução de Código

root@kitploit:~
const uint32_t program[] = {
    0x200415b7,  // lui  a1, 0x20040
    0xabcd0537,  // lui  a0, 0xabcd0
    0x00a5a223,  // sw   a0, 4(a1)
    0x0000006f,  // j    . (loop)
};

rp2350_execute_code(target, 0, 0x20000000, program, 4);

Envia para a SRAM de destino, verifica, define o PC, retoma.

Rastreamento de Instruções

root@kitploit:~
bool on_instruction(const trace_record_t *rec, void *ctx) {
    printf("0x%08x: 0x%08x\n", rec->pc, rec->instruction);
    return true;
}

int traced = rp2350_trace(target, 0, 100, on_instruction, NULL, false);

Executa passo a passo através de instruções via DCSR.step. ~5ms por instrução sem captura de registradores, ~80ms com captura completa de registradores.

Buffer de Programa

Execução direta de instruções RISC-V no contexto de depuração:

root@kitploit:~
uint32_t progbuf[] = {
    0x34202473,  // csrr s0, mcause
    0x00100073   // ebreak
};
rp2350_execute_progbuf(target, 0, progbuf, 2);
swd_result_t mcause = rp2350_read_reg(target, 0, 8);

O acesso a CSR usa isso internamente, pois o Hazard3 não suporta comandos CSR abstratos.

Compilação

root@kitploit:~
add_subdirectory(lib/pico2-swd-riscv)
target_link_libraries(your_app pico2_swd_riscv)

Verbosidade de depuração (tempo de compilação):

root@kitploit:~
set(PICO2_SWD_DEBUG_LEVEL 3)  # 0=none, 1=warn, 2=info, 3=debug

Internals

Protocolo de Fio (Wire Protocol)

SWD usa pacotes de requisição de 8 bits (start, APnDP, RnW, addr[3:2], parity, stop, park), ACK de 3 bits (OK=1, WAIT=2, FAULT=4) e fases de dados de 33 bits com paridade. Ciclos de turnaround lidam com mudanças de direção do SWDIO. Respostas WAIT são repetidas automaticamente (padrão: 5 tentativas, backoff de 100us).

Codificação RP2350 DP_SELECT

Não padrão: [15:12]=APSEL, [11:8]=0xD, [7:4]=bank, [0]=ctrlsel. O 0xD nos bits[11:8] é necessário, mas não documentado.

Ativação do DM

Handshake de três fases através do Bank 1 CSW: desativar (0x00000000), ativar (0x00000001), configuração completa (0x07FFFFC1). Resposta de status esperada: 0x04010001.

Acesso a Registradores

GPRs via comandos abstratos (regno 0x1000+n, transferência de 32 bits). CSRs via buffer de programa: salvar s0, executar csrr s0, <csr> ou csrw <csr>, s0, ler/restaurar s0.

Acesso ao Barramento do Sistema

SBCS configurado com sbaccess=32bit e sbreadonaddr. Escrever SBADDRESS0 aciona a leitura do barramento; dados disponíveis imediatamente em SBDATA0. Transferências em bloco habilitam sbautoincrement para leituras/escritas em streaming sem configuração de endereço por palavra.

Passo Único (Single-Step)

Ler DCSR via progbuf, definir o bit de passo (bit 2), retomar o hart. O hart executa uma instrução e reentra no modo de depuração. Limpar o bit de passo depois.

Limitações

  • Sem breakpoints de hardware (módulo de trigger removido, planejado para reimplementação)
  • Sem SWD multi‑drop
  • Sem decodificação de instruções comprimidas (lê corretamente, não decodifica mnemônicos)
  • Sem programação flash (possível via rp2350_execute_code com um stub)
  • Sem perfilagem com precisão de ciclo

Referências

  • RISC-V External Debug Support v0.13
  • ARM Debug Interface Architecture Specification ADIv5/v6
  • RP2350 Datasheet, Capítulo 3.5
  • ARM CoreSight SWD-DP Technical Reference Manual

Licença

MIT. Veja LICENSE.

Baixar ferramenta