NET mlžení tools / strategie




Můj výrobek má několik složek: ASP.NET, Windows Forms App a Windows Service. 95% nebo tak kódu je napsáno v VB.NET.


Z důvodů k duševnímu vlastnictví, musím poplést kódu, a to až do teď jsem používal verzi Dotfuscator který je nyní více než 5 let. Myslím, že je čas přejít na nový nástroj generace. To, co jsem hledal je uveden seznam požadavků, které bych měl zvážit při hledání nového obfuscator.


To, co vím, že by měl vypadat tak daleko:


* ***Serialization / De-serializace*** . Podle mého stávajícího řešení, jsem prostě říct, nástroj **není** poplést žádné členy třída data, protože ta bolest není schopen načíst data, která byla dříve serializovat je prostě příliš velký.
* ***Integrace s procesu sestavení***
* ***Práce s ASP.NET*** . V minulosti jsem našel toto problematické kvůli změně jména DLL (které často mají jeden na straně) - což ne všechny nástroje zvládne dobře.
Zpět s .Net 1.1 zmatek byl nezbytný: rozklad kód byl jednoduchý, a ty by mohly jít ze sestavy, IL, do kódu C # a mít ji znovu sestaven s velmi malým úsilím.


Nyní s .Net 3.5 Nejsem si vůbec jistý. Zkuste dekompilace 3,5 sestavu; co dostanete, je dlouhá cesta z kompilace.


Přidejte optimalizací od 3,5 (mnohem lepší než 1.1) a způsob, jakým anonymní typy, delegátů a tak dále jsou zpracovány pomocí odrazu (jsou to noční můra překompilovat). Přidejte lambda výrazy, kompilátor ‚magic‘ jako Linq-syntaxe a `var`a C # 2 funkce, jako je `yield`(což má za následek nové třídy s nečitelné názvy). Váš rozložit kód končí dlouhá cesta od kompilovatelný.


Profesionální tým se spoustou času může ještě zvrátit zpět inženýr, ale pak totéž platí o jakémkoliv pozměněném kódu. Jaký kód se dostali ven, že by neudržitelný a vysoce pravděpodobné, že bude velmi buggy.


Doporučuji key-podepisování sestavení (to znamená, pokud hackeři mohou překompilovat jednu budou muset překompilovat všechny), ale nemyslím si, že mlžení to stojí za to.
V současné době jsou v kurzu SQL dartabáze. Takže pokud se chceš uplatnit, tak MS-SQL, Interbase, ORACLE, popř. nějaké ty internetové jako např. MySQL, PostgreeSQL apod. Každá databáze má vlastní programovací jazyk pro uložené procedury, vlastní datové typy apod.Program, ve kterém budeš vyvíjet soft je opět něco jiného. Ten většinou je univerzální a umí přistupovat k jakékoliv databázi.V současné době, pokud bych začínal, tak bych se orientoval směrem .NET a C#. Systém Windows vyžaduje rozhraní .NET Framework 4.5.2 nebo 4.6.[https://www.canon.cz/printers/pixma-ts205-seri...](https://www.canon.cz/printers/pixma-ts205-series/specifications/) <p>psaní plynulého rozhraní (s ním jsem <a href="http://www.google.ca/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0cbuqfjaa&amp;url=http%3a%2f%2fsoapboxautomation.com%2fproducts%2ffluentdwelling%2f&amp;ei=ao6ttcuck8sdgqesvpsqda&amp;usg=afqjcngcf99lzbzlrfvnrtst7qsww3kxwg">dabbled</a> ) vyžaduje více úsilí, ale má to výplaty, protože pokud to uděláte správně, je výsledný uživatelský kód jasnější. je to v zásadě forma specifického jazykového jazyka.</p><p>jinými slovy, pokud je váš kód načten mnohem více, než je napsán (a jaký kód není?), měli byste zvážit vytvoření plynulého rozhraní.</p><p>plynulá rozhraní jsou více o kontextu a jsou mnohem víc než jen způsoby konfigurace objektů. jak vidíte ve výše uvedeném odkazu, k dosažení:</p><ol> <li>kontext (takže když obvykle provádíte mnoho akcí ve stejném pořadí, můžete je zřetězit, aniž byste museli znovu a znovu prohlašovat svůj kontext).</li> <li>viditelnost (když jdete na <code>objecta.</code> pak vám inteligence dává spoustu rad. v mém případě výše, <code>plm.led.</code> vám poskytuje všechny možnosti pro ovládání vestavěné led a <code>plm.network.</code> vám poskytuje věci, které můžete dělat se síťovým rozhraním. <code>plm.network.x10.</code> vám dává podmnožinu síťových akcí pro zařízení x10. u inicializátorů konstruktoru to nedostanete (pokud si nepřejete, aby byl objekt konstruován pro každý jiný typ akce, který není idiomatický).</li> <li>reflexe (nepoužívá se ve výše uvedeném příkladu) - schopnost převzít výraz linq a manipulovat s ním je velmi výkonný nástroj, zejména v některých pomocných api, které jsem vytvořil pro testy jednotek. dokážu předat výraz getter get, sestavit spoustu užitečných výrazů, zkompilovat a spustit je, nebo dokonce použít getter k nastavení mého kontextu.</li> </ol><p>jedna věc, kterou obvykle dělám, je:</p><pre><code>test.property(t =&gt; t.someproperty) .initializedto(string.empty) .cantbenull() // tries to set to null and asserts argumentnullexception .yaddayadda(); </code></pre><p>nechápu, jak můžete něco takového udělat i bez plynulého rozhraní.</p><p><strong> edit 2 </strong>: můžete také udělat opravdu zajímavá vylepšení čitelnosti, jako například:</p><pre><code>test.listproperty(t =&gt; t.mylist) .shouldhave(18).items() .andthenafter(t =&gt; testaddingitemtolist(t)) .shouldhave(19).items(); </code></pre> <p>vyvinul jsem skutečné aplikace s oběma rails a asp.net mvc), ale tato odpověď přichází se značnou výzvou: naučil jsem se a vyvíjel se s předběžnou verzí 2 rails, takže je zcela možné, že jsem jsem nesmírně zastaralý díky mým znalostem rails).</p><p>jak už bylo řečeno, nemyslím si, že existuje <em> cokoli </em>, které lze s jedním, ale ne s druhým. vzhledem k jakémukoli souboru požadavků na webovou aplikaci byste měli být schopni sestavit tuto aplikaci - pravděpodobně stejně efektivně - pomocí rails nebo asp.net mvc).</p><p>existuje několik úhledných věcí, které - podle mého nejlepšího vědomí - jsou k dispozici v asp.net mvc hlavně kvůli aspektům c # /. net. například: když mám stránku, která obsahuje odeslaný formulář, mám akci, která zkontroluje, zda se jedná o get, nebo post), abych rozhodla, co dělat:</p><pre><code>def edit @item = item.find(params[:id]) if request.post? @item.update\_attributes(params[:item]) redirect\_to :action =&gt; 'edit', :id =&gt; @item.id end end </code></pre><p>toto je triviální příklad, ale <code>if request.post?</code> vzor je v rails velmi běžný. v netriviálních případech může být kód akce velký a chaotický a často bych si přál, abych ho mohl čistě promítnout do samostatných metod. v asp.net mvc to mohu udělat:</p><pre><code>public actionresult edit() { // render my page that has the edit form ... } [httppost] public actionresult edit(foothing foo) { // save my foothing data ... } </code></pre><p>myslím, že schopnost čistě oddělit vyřizování žádostí get a post žádostí) je elegantní. váš počet najetých kilometrů se může lišit.</p><p>další věc, kterou asp.net mvc dělá, že je super v pohodě (opět podle mého názoru), souvisí také s manipulací s posts. v rails musím dotazovat <code>params</code> hash pro všechny mé proměnné formuláře. řekněme, že mám formulář s poli „status“, „gonkulated“, „invert“ a „dispozice“:</p><pre><code>def edit @item = item.find(params[:id]) if params[:status] == "new" ... else ... end if params[:gonkulated] == "true" ... else ... end if params[:invert] == "true" ... else ... end # rest ommited for brevity end </code></pre><p>ale asp.net mvc úhledně mi umožňuje získat všechny hodnoty formuláře jako parametry mé metody akce:</p><pre><code>[httppost] public actionresult edit(int id, string status, bool gonkulated, bool invert, int disposition) { ... } </code></pre><p>to jsou dvě věci, které se mi na asp.net mvc nebo rails opravdu líbily. <strong><em> nestačí, aby si nějaký rozumný nebo kompetentní vývojář vybral jeden rámec nad druhým. </em></strong></p> <p>použít <a href="http://msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx"><code>stringwriter</code></a> namísto souboru <a href="http://msdn.microsoft.com/en-us/library/system.io.streamwriter.aspx"><code>streamwriter</code></a> :</p><pre><code>public static string serializeobject&lt;t&gt;(this t toserialize) { xmlserializer xmlserializer = new xmlserializer(toserialize.gettype()); using(stringwriter textwriter = new stringwriter()) { xmlserializer.serialize(textwriter, toserialize); return textwriter.tostring(); } } </code></pre><p>poznámka: je důležité použít <code>toserialize.gettype()</code> namísto <code>typeof(t)</code> v konstruktoru xmlserializer: pokud použijete první, kód pokrývá všechny možné podtřídy <code>t</code> (které jsou pro metodu platné), zatímco druhý z nich selže při předávání typu odvozeného z <code>t</code>. zde je odkaz s nějakým příkladem kódu, který motivuje toto prohlášení, s <code>xmlserializer</code> házením <code>exception</code>, když je <code>typeof(t)</code> použito, protože předáte instanci odvozeného typu metodě, která volá serializeobject, který je definované v základní třídě odvozeného typu: <a href="http://ideone.com/1z5j1">http://ideone.com/1z5j1</a> .</p><p>ideone také používá mono ke spuštění kódu; skutečný <code>exception</code> byste dostali pomocí runtime microsoft .net má jiný <code>message</code> než ten, který je zobrazen na ideone, ale to selže stejně.</p> <p>myslím, že otázka je:</p><blockquote> <p>"jak mohu získat přesně to, co chci od svých uživatelů tím, že jim vstup nesmyslně usnadní?"</p> </blockquote><p>jedinou instancí, kde vidím uživatele, kteří skutečně potřebují používat html přímo v nějaké formě vstupu, je, když/pokud formátují tabulková data. v takovém případě je však mnohem snazší dát jim formu, která dokáže udělat totéž, nebo jakoukoli z populárních sítí dostupných v různých knihovnách.</p><p>myslím, že zlatým pravidlem je, alespoň pro mě, použití systému značkování, které není html, které mohou vaši zpracovatelé formulářů použít k vytvoření krásného, ​​standardu vyhovujícího a sémanticky správného html.</p><p>skenery třetích stran mohou (obvykle) detekovat většinu problémů s nahranými soubory. osobně se mi líbí clamav - který je k dispozici pro * nix i windows.</p><p>to řeší problém zajistit, že je vše uspořádáno pěkně, správně naformátováno a návštěvníkům nejsou podávány žádné nežádoucí věci, nebo je to tak?</p><p>druhou věcí, kterou musíte udělat, je zkontrolovat jakýkoli obsah, který předloží, člověk musí mít na tom nějakou roli, nebo bude něco chybět. je tento obrázek vhodný? vede tento odkaz k malwaru nebo k něčemu jinému, na co byste raději nechtěli odkazovat? atd.</p><p>poskytnutí mechanismu označování pomáhá, ale není vždy účinné. pokud například na stackoverflow.com odpovíte na dvouletou otázku, otázka se okamžitě přesune na titulní stránku, kde komunita určitě zkontroluje, co bylo právě přidáno. ne všechny systémy jsou navrženy s ohledem na tento druh ochrany.</p><p>pokud uděláte značné množství svazku, pokud jde o obsah příspěvků od uživatelů, pravděpodobně stojí za to prozkoumat pomocí dodavatelů, kteří jednoduše zkontrolují podání a ujistí se, že nevhodná média/odkazy jsou rychle vyřazeny. nebo si možná můžete vyhledat pomoc od své komunity uživatelů (pokud existuje), aby udělali totéž, výměnou za nějaký druh zvláštních privilegií nebo výhod, které běžní uživatelé nemají rádi.</p> <p>databázi na straně serveru a programovací jazyk, který vyberete, je zcela na vás, protože zákazník nebude vědět, ani se nestará o to, v jakém jazyce je napsán, dokud bude fungovat. a protože ovládáte prostředí serveru, můžete použít cokoli, co chcete. vyberte si programovací jazyk a databázi, se kterou váš tým bude snadno pracovat a bude nejznámější.</p><p>pokud jde o stranu klienta, nemusíte si vybírat mezi flashem nebo javascriptem. můžete použít oba, pokud slouží určitému účelu. pokud je něco jednoduše animací kvůli animaci, flash je dobrá volba, protože je snadné vytvářet animace. a pokud někdo nemá přístup k blesku, například na mobilním zařízení, nebude mu chybět žádná funkčnost. pokud jsou animované bity funkční částí webové stránky, javí se javascript jako dobrý nástroj k použití.</p><p>fyi, ve webdesignu a programování není nic takového jako „příliš starý“. k dispozici je pouze ten správný nástroj a ne.</p> <p>ve skriptech shell není důležité žádné odsazení.</p><p>mírně méně flippant odpověď:</p><ul> <li>vyberte si ve svém týmu standard, se kterým můžete pracovat, zjednodušit věci.</li> <li>použijte něco, co editor usnadňuje, takže nemusíte bojovat, abyste se drželi standardu.</li> </ul> Často toto je provedeno pomocí [„Data Driven odběry“](https://msdn.microsoft.com/en-us/library/ms169673.aspx) , ale tato funkce je k dispozici pouze v některých SQL vydáních: Enterprise a Business Intelligence, ale ne v normě.


Takže existuje celá řada kreativních řešení. Ale nemám rád žádné z nich, a všechny vyžadují spravedlivý trochu práce mimo SSRS.


Mezi řešení, které jsem viděl, patří: Vytvoření odběr a potom zakázání nebo povolení SQL úlohu, kterou odešle předplatné (identifikovatelné podle GUID).


Vytvořte si .NET obálky exe zvládnout odeslání e-mailu. Je možné spustit dotaz nejprve zjistit, kolik se vrací řádky, a pak v případě potřeby generovat zprávu a zahrnout do e-mailu. <p>příkaz <code>merge</code> má složitou syntaxi a ještě složitější implementaci, ale v zásadě jde o spojení dvou tabulek, filtrování dolů na řádky, které je třeba změnit (vložit, aktualizovat nebo smazat), a poté provést požadované změny. vzhledem k těmto vzorovým údajům:</p><pre><code>declare @categoryitem as table ( categoryid integer not null, itemid integer not null, primary key (categoryid, itemid), unique (itemid, categoryid) ); declare @datasource as table ( categoryid integer not null, itemid integer not null primary key (categoryid, itemid) ); insert @categoryitem (categoryid, itemid) values (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 5), (3, 6), (4, 5); insert @datasource (categoryid, itemid) values (2, 2); </code></pre><p><strong> cíl </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 2 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 3 ║ ║ 3 ║ 5 ║ ║ 4 ║ 5 ║ ║ 3 ║ 6 ║ ╚════════════╩════════╝ </code></pre><p><strong> zdroj </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>požadovaným výsledkem je nahrazení dat v cíli daty ze zdroje, ale pouze pro <code>categoryid = 2</code>. po výše uvedeném popisu <code>merge</code> bychom měli napsat dotaz, který spojuje zdroj a cíl pouze na klíče, a filtrovat řádky pouze v klauzulích <code>when</code>:</p><pre><code>merge into @categoryitem as target using @datasource as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by source and target.categoryid = 2 then delete when not matched by target and source.categoryid = 2 then insert (categoryid, itemid) values (categoryid, itemid) output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>to dává následující výsledky:</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 2 ║ ║ 3 ║ 5 ║ ║ 3 ║ 6 ║ ║ 4 ║ 5 ║ ╚════════════╩════════╝ </code></pre><p>realizační plán je: <img src="https://i.stack.imgur.com/fovhu.jpg" alt="merge plan"></p><p>všimněte si, že jsou obě tabulky plně naskenovány. můžeme to považovat za neefektivní, protože pouze řádky, kde <code>categoryid = 2</code> bude ovlivněno v cílové tabulce. zde přicházejí varování v books online. jeden chybný pokus o optimalizaci, aby se dotkl pouze nezbytných řádků v cíli, je:</p><pre><code>merge into @categoryitem as target using ( select categoryid, itemid from @datasource as ds where categoryid = 2 ) as source on source.itemid = target.itemid and target.categoryid = 2 when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>logika v klauzuli <code>on</code> je použita jako součást spojení. v tomto případě je spojení úplným vnějším spojením (viz <a href="http://technet.microsoft.com/en-us/library/bb522522%28v=sql.105%29.aspx">tento záznam books online</a> proč). použití kontroly kategorie 2 na cílových řádcích jako součásti vnějšího spojení nakonec povede k odstranění řádků s jinou hodnotou (protože neodpovídají zdroji):</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 1 ║ 1 ║ ║ delete ║ 1 ║ 2 ║ ║ delete ║ 1 ║ 3 ║ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ║ delete ║ 3 ║ 5 ║ ║ delete ║ 3 ║ 6 ║ ║ delete ║ 4 ║ 5 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>kořenová příčina je ze stejného důvodu, proč se predikáty chovají v klauzuli vnější spojení <code>on</code> odlišně, než když jsou specifikovány v klauzuli <code>where</code>. syntaxe <code>merge</code> (a implementace spojení v závislosti na zadaných klauzulích) jen ztěžují vidět, že tomu tak je.</p><p> <a href="http://technet.microsoft.com/en-us/library/bb510625%28v=sql.105%29.aspx">navádění v books online</a> (rozšířeno v položce <a href="http://technet.microsoft.com/en-us/library/cc879317%28v=sql.105%29.aspx">optimizing performance</a> ) nabízí navádění, které zajistí, že správná sémantika je vyjádřena pomocí syntaxe <code>merge</code>, aniž by uživatel nutně musel muset pochopit všechny podrobnosti implementace nebo zohlednit způsoby, kterými by optimalizátor mohl legitimně přeskupit věci z důvodů efektivnosti provádění.</p><p>dokumentace nabízí tři možné způsoby implementace časného filtrování:</p><p><strong> zadání podmínky filtrování v klauzuli <code>when</code> </strong> zaručuje správné výsledky, ale může znamenat, že více řádků je čteno a zpracováno ze zdroje a cíle tabulky, než je nezbytně nutné (viz první příklad).</p><p><strong> aktualizace prostřednictvím zobrazení </strong>, která obsahuje podmínku filtrování, také zaručuje správné výsledky (protože změněné řádky musí být přístupné pro aktualizaci prostřednictvím zobrazení), ale vyžaduje to vyhrazené zobrazení, které splňuje liché podmínky pro aktualizaci zobrazení.</p><p><strong> použití společného výrazu tabulky </strong> přináší podobné riziko při přidávání predikátů k klauzuli <code>on</code>, ale z poněkud odlišných důvodů. v mnoha případech to bude bezpečné, ale vyžaduje to odbornou analýzu prováděcího plánu, aby se to potvrdilo (a rozsáhlé praktické testování). například:</p><pre><code>with target as ( select * from @categoryitem where categoryid = 2 ) merge into target using ( select categoryid, itemid from @datasource where categoryid = 2 ) as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>výsledkem jsou správné výsledky (neopakované) s optimálnějším plánem:</p><p><img src="https://i.stack.imgur.com/tazmk.jpg" alt="merge plan 2"></p><p>plán čte pouze řádky pro kategorii 2 z cílové tabulky. to může být důležitým hlediskem výkonu, pokud je cílová tabulka velká, ale je příliš snadné tuto chybu získat pomocí syntaxe <code>merge</code>.</p><p>někdy je snazší zapsat <code>merge</code> jako samostatné operace dml. tento přístup může dokonce <strong> vést lépe </strong> než jediný <code>merge</code>, což je skutečnost, která lidi často překvapuje.</p><pre><code>delete ci from @categoryitem as ci where ci.categoryid = 2 and not exists ( select 1 from @datasource as ds where ds.itemid = ci.itemid and ds.categoryid = ci.categoryid ); insert @categoryitem select ds.categoryid, ds.itemid from @datasource as ds where ds.categoryid = 2; </code></pre>