📄 smbtransaction.c
字号:
#include "headers.h"typedef struct Args Args;struct Args { ulong pcount; ulong poffset; ulong pdisplacement; ulong dcount; ulong doffset; ulong ddisplacement; uchar scount;};int_smbtransactiondecodeprimary(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, int hasname, char **errmsgp){ ushort poffset, doffset; if (h->wordcount < 14) { smbstringprint(errmsgp, "word count less than 14"); return -1; } t->in.scount = pdata[13 * 2]; if (h->wordcount != 14 + t->in.scount) { smbstringprint(errmsgp, "smbcomtransaction: word count invalid\n"); return -1; } t->in.tpcount = smbnhgets(pdata); pdata += 2; t->in.tdcount = smbnhgets(pdata); pdata += 2; t->in.maxpcount = smbnhgets(pdata); pdata += 2; t->in.maxdcount = smbnhgets(pdata); pdata += 2; t->in.maxscount = *pdata++; pdata++; t->in.flags = smbnhgets(pdata); pdata += 2; pdata += 4; /* timeout */ pdata += 2; t->in.pcount = smbnhgets(pdata); pdata += 2; poffset = smbnhgets(pdata); pdata += 2; t->in.dcount = smbnhgets(pdata); pdata += 2; doffset = smbnhgets(pdata); pdata += 2; pdata++; /* scount */ pdata++; /* reserved */ smbfree(&t->in.setup); if (t->in.scount) { int x; t->in.setup = smbemalloc(t->in.scount * sizeof(ushort)); for (x = 0; x < t->in.scount; x++) { t->in.setup[x] = smbnhgets(pdata); pdata += 2; } } smbfree(&t->in.name); if (hasname && !smbbuffergetstring(b, h, SMB_STRING_PATH, &t->in.name)) { smbstringprint(errmsgp, "not enough bdata for name"); return -1; } if (poffset + t->in.pcount > smbbufferwriteoffset(b)) { smbstringprint(errmsgp, "not enough bdata for parameters"); return -1; } if (t->in.pcount > t->in.tpcount) { smbstringprint(errmsgp, "too many parameters"); return -1; } smbfree(&t->in.parameters); t->in.parameters = smbemalloc(t->in.tpcount); memcpy(t->in.parameters, smbbufferpointer(b, poffset), t->in.pcount); if (doffset + t->in.dcount > smbbufferwriteoffset(b)) { smbstringprint(errmsgp, "not enough bdata for data"); return -1; } if (t->in.dcount > t->in.tdcount) { smbstringprint(errmsgp, "too much data"); return -1; } smbfree(&t->in.data); t->in.data = smbemalloc(t->in.tdcount); memcpy(t->in.data, smbbufferpointer(b, doffset), t->in.dcount); if (t->in.dcount < t->in.tdcount || t->in.pcount < t->in.tpcount) return 0; return 1;}intdecoderesponse(SmbTransaction *t, Args *a, SmbBuffer *b, char **errmsgp){ if (t->out.tpcount > smbbufferwritemaxoffset(t->out.parameters)) { smbstringprint(errmsgp, "decoderesponse: too many parameters for buffer"); return 0; } if (t->out.tdcount > smbbufferwritemaxoffset(t->out.data)) { smbstringprint(errmsgp, "decoderesponse: too much data for buffer"); return 0; } if (a->pdisplacement + a->pcount > t->out.tpcount) { smbstringprint(errmsgp, "decoderesponse: more parameters than tpcount"); return 0; } if (a->pdisplacement != smbbufferwriteoffset(t->out.parameters)) { smbstringprint(errmsgp, "decoderesponse: parameter displacement inconsistent"); return 0; } if (a->ddisplacement + a->dcount > t->out.tdcount) { smbstringprint(errmsgp, "decoderesponse: more data than tdcount"); return 0; } if (a->ddisplacement != smbbufferwriteoffset(t->out.data)) { smbstringprint(errmsgp, "decoderesponse: data displacement inconsistent"); return 0; } assert(a->scount == 0); if (a->pcount) { if (!smbbufferreadskipto(b, a->poffset)) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: invalid parameter offset"); return 0; } if (!smbbuffercopy(t->out.parameters, b, a->pcount)) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: not enough data for parameters"); return 0; } } if (a->dcount) { if (!smbbufferreadskipto(b, a->doffset)) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: invalid data offset"); return 0; } if (!smbbuffercopy(t->out.data, b, a->dcount)) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: not enough data for data"); return 0; } } return 1;}intsmbtransactiondecoderesponse(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp){ Args a; if (h->command != SMB_COM_TRANSACTION) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: not an SMB_COM_TRANSACTION"); return 0; } if (h->wordcount < 10) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: word count less than 10"); return -1; } t->out.tpcount = smbnhgets(pdata); pdata += 2; t->out.tdcount = smbnhgets(pdata); pdata += 2; pdata += 2; a.pcount = smbnhgets(pdata); pdata += 2; a.poffset = smbnhgets(pdata); pdata += 2; a.pdisplacement = smbnhgets(pdata); pdata += 2; a.dcount = smbnhgets(pdata); pdata += 2; a.doffset = smbnhgets(pdata); pdata += 2; a.ddisplacement = smbnhgets(pdata); pdata += 2; a.scount = *pdata; if (a.scount != h->wordcount - 10) { smbstringprint(errmsgp, "smbtransactiondecoderesponse: scount inconsistent"); return 0; } return decoderesponse(t, &a, b, errmsgp);}intsmbtransactiondecoderesponse2(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp){ Args a; if (h->command != SMB_COM_TRANSACTION2) { smbstringprint(errmsgp, "smbtransactiondecoderesponse2: not an SMB_COM_TRANSACTION2"); return 0; } if (h->wordcount < 10) { smbstringprint(errmsgp, "smbtransactiondecoderesponse2: word count less than 10"); return -1; } t->out.tpcount = smbnhgets(pdata); pdata += 2; t->out.tdcount = smbnhgets(pdata); pdata += 2; pdata += 2; a.pcount = smbnhgets(pdata); pdata += 2; a.poffset = smbnhgets(pdata); pdata += 2; a.pdisplacement = smbnhgets(pdata); pdata += 2; a.dcount = smbnhgets(pdata); pdata += 2; a.doffset = smbnhgets(pdata); pdata += 2; a.ddisplacement = smbnhgets(pdata); pdata += 2; a.scount = *pdata; if (a.scount != h->wordcount - 10) { smbstringprint(errmsgp, "smbtransactiondecoderesponse2: scount inconsistent"); return 0; } return decoderesponse(t, &a, b, errmsgp);}intsmbtransactiondecodeprimary(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp){ return _smbtransactiondecodeprimary(t, h, pdata, b, 1, errmsgp);}intsmbtransactiondecodeprimary2(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp){ return _smbtransactiondecodeprimary(t, h, pdata, b, 0, errmsgp);}voidsmbtransactionfree(SmbTransaction *t){ free(t->in.parameters); free(t->in.data); free(t->in.setup); free(t->in.name); smbbufferfree(&t->out.parameters); smbbufferfree(&t->out.data);}static int_transactionencodeprimary(SmbTransaction *t, uchar cmd, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob, uchar *wordcountp, ushort *bytecountp, char **errmsgp){ SmbHeader mh; ulong countsfixupoffset, bytecountfixupoffset; int x; mh = *h; *wordcountp = mh.wordcount = 14 + t->in.scount; mh.flags &= ~SMB_FLAGS_SERVER_TO_REDIR; mh.command = cmd; if (!smbbufferputheader(ob, &mh, p)) { toosmall: smbstringprint(errmsgp, "output buffer too small"); return 0; } if (t->in.tpcount > 65535 || t->in.tdcount > 65535 || t->in.maxpcount > 65535 || t->in.maxdcount > 65535) { smbstringprint(errmsgp, "counts too big"); return 0; } if (!smbbufferputs(ob, t->in.tpcount) || !smbbufferputs(ob, t->in.tdcount) || !smbbufferputs(ob, t->in.maxpcount) || !smbbufferputs(ob, t->in.maxdcount) || !smbbufferputb(ob, t->in.maxscount) || !smbbufferputb(ob, 0) || !smbbufferputs(ob, t->in.flags) || !smbbufferputl(ob, 0) || !smbbufferputs(ob, 0)) goto toosmall; countsfixupoffset = smbbufferwriteoffset(ob); if (!smbbufferputs(ob, 0) || !smbbufferputs(ob, 0) || !smbbufferputs(ob, 0) || !smbbufferputs(ob, 0)) goto toosmall;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -