ufrisk / pcileech-fpga

FPGA modules used together with the PCILeech Direct Memory Access (DMA) Attack Software
913 stars 206 forks source link

initiating tlp writes from fpga #53

Closed nazarihome closed 4 years ago

nazarihome commented 4 years ago

First, I'd like to thank you for this great piece of work! Please forgive me if my question is too naive. I am trying to use pcileech-fpga code to perform some memory writes without requests from control computer. As far as I understand right now pcileech_com.sv has this code for initial tlps.

bit [63:0] initial_rx [5] = '{
            // Modify data below to set own actions - examples:
            // - send some initial TLP on core startup.
            // - set initial VID/PID if PCIe core has been modified.
            // - write to DRP memory space to alter the core.
            // replace / expand on dummy values below - for syntax of each 64-bit word
            // please consult sources and also device_fpga.c in the LeechCore project.
            64'h00000000_00000000,
            64'h00000000_00000000,
            64'h00000000_00000000,
            64'h00000000_00000000,
            // Bring the PCIe core online from initial hot-reset state. This is done by
            // setting control bit in PCIleech FOFO CMD register. This should ideally be
            // done after DRP&Config actions are completed - but before sending PCIe TLPs.
            64'h00000003_80182377
 };

suppose that I want to perform a memory write at initialization same as this: pcileech tlp -in 60000002090080ff00000000c00000000000000012345678 -device rawudp://ip=192.168.0.222 -vvv

To my understanding of device_fpga.c, I should add this to bottom of initial_rx:

            64'h60000002_00000077,
            64'h090080ff_00000077,
            64'h00000000_00000077, 
            64'hc0000000_00000077,
            64'h00000000_00000077,
            64'h12345678_00000477

But Is that all I need to add? because when I check the address, the data is not written though. I have realized that when I run pcileech tlp -in 60000002090080ff00000000c00000000000000012345678 -device rawudp://ip=192.168.0.222 -vvv multiple UDP packets are sent before and after the packet with this data. I was wondering if I am missing something and I need to send some commands before and after this tlp packet as well.

ufrisk commented 4 years ago

I'm a bit unsure about this, it was a while since I looked into it and it's not well tested. I assume you updated the size of the array from 5 up to your value.

You can try to add a few blanks, 10 or so, 64'h00000000_00000000, in-between if your code and the last line if it has something with the core needing a few CLKs to come out of reset before receiving your TLPs.

Another explanation might be that it's indeed sent; but overwritten by the computer some time afterwards.


There is also an option to transmit static TLP a set number of times with variable retransmit waits. That functionality may be a bit more suitable.

Play around with it from within a re-compiled version of PCILeech/LeechCore first; set the registers correctly and then enable by writing to the RETRANSMIT COUNT register.

https://github.com/ufrisk/pcileech-fpga/blob/20526265dea28b43002dcc3c6ad359e3dd57c15b/NeTV2/src/pcileech_pcie_cfg_a7.sv#L244

Once it's working just hard code it into the FPGA bitstream.


The other packets is just PCILeech asking the device for version numbers on the bitstream and such. For most functions (except the tlp command) it also tries to auto-detect max memory which is quite a few packets...

ufrisk commented 4 years ago

I assume you managed to fix this issue somehow. If not, please reopen the issue.